Ответ 1
Используйте это:
string area = areaObject.GetType().GetProperty("area").GetValue(areaObject, null);
У меня есть следующий метод:
public void MyMethod(object obj){
// implement
}
И я называю это следующим образом:
MyMethod(new { myparam= "waoww"});
Итак, как я могу реализовать MyMethod()
для получения значения myparam?
Edit
Я использую это:
dynamic d= obj;
string param = d.myparam;
но ошибка увеличивается:
'object' does not contain a definition for 'myparam'
Также я использую точку останова, и я вижу, что d имеет свойство myparam string.
И есть ли способ проверить динамический тип, если он содержит любое свойство, подобное этому:
if(d.contain(myparam))?
Изменить II
Это мой основной код:
public static MvcHtmlString SecureActionLink(this HtmlHelper htmlHelper,
string linkText, string actionName, string controllerName,
object routeValues, object htmlAttributes) {
string areaName =
(string)htmlHelper.ViewContext.RouteData.DataTokens["area"];
dynamic areaObject = routeValues;
if(areaObject != null && !string.IsNullOrEmpty(areaObject.area))
areaName = areaObject.area;
// more
}
и назовите его как:
<p>@Html.SecureActionLink("Secure Link between Areas", "Index", "Context",
new { area = "Settings" }, null)</p>
И ошибка:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a
definition for 'area'
Line 303: dynamic areaObject = routeValues;
Line 304:
Line 305: if(areaObject != null && !string.IsNullOrEmpty(areaObject.area))
Line 306: areaName = areaObject.area;
Line 307:
Source File: D:\Projects\MyProject\HtmlHelpers\LinkExtensions.cs Line: 305
Изменить III
Это мое AssemblyInfo определения HtmlHelper:
[assembly: AssemblyTitle("MyProject.Presentation")]
[assembly: InternalsVisibleTo("cpanel.MyProject.dev")]
но еще есть ошибка: 'object' does not contain a definition for 'area'
Я использую разные сборки, но как это возможно, когда я использую точку останова, я вижу, что у моего динамического areaobject
есть свойство name area
, а также я могу видеть его значение, но ошибка говорит: 'object' does not contain a definition for 'area'
t как это возможно?
Edit
Я изменяю сборку, и теперь динамический тип является внутренним, но ошибка остается прежней
Используйте это:
string area = areaObject.GetType().GetProperty("area").GetValue(areaObject, null);
Ну, вы можете использовать динамическую типизацию, если используете С# 4:
public void MyMethod(object obj) {
dynamic d = obj;
Console.WriteLine(d.myparam);
}
Он задает вопрос, почему вы не используете именованный тип. Анонимные типы на самом деле не предназначены для совместного использования между различными способами.
EDIT: обратите внимание, что если это в другой сборке для исходного кода, создающего объект, вам нужно будет использовать [InternalsVisibleTo]
поскольку анонимные типы являются внутренними.
Прежде всего, как говорили другие, не делайте этого в первую очередь. Это не то, как предполагается использовать анонимные типы.
Во-вторых, если вы настроены на это, существует несколько способов сделать это. Медленным и опасным способом является использование динамического, как говорили другие.
Быстро и опасно использовать "cast by example":
static T CastByExample<T>(object obj, T example)
{
return (T)obj;
}
static void M(object obj)
{
var anon = CastByExample(obj, new { X = 0 });
Console.WriteLine(anon.X); // 123
}
static void N()
{
M(new { X = 123 });
}
Есть ли способ проверить динамический тип, если он содержит какое-либо свойство?
Используйте Reflection. Конечно, если вы собираетесь использовать Reflection, тогда нет необходимости использовать динамику в первую очередь. Вы используете динамическое, чтобы избежать использования Reflection, поэтому, если вы собираетесь использовать Reflection, вы можете просто продолжать использовать его.
Похоже, вы пытаетесь сделать что-то, что трудно сделать на С#. Я бы пересмотрел, хотите ли вы это сделать, и если вы это сделаете, является ли С# языком для вас. Динамический язык, такой как IronPython, может быть лучше подходит для вашей задачи.
Все говорят "не делай этого в первую очередь", но это именно то, что делает asp.mvc! (Не поймите меня неправильно, мне это не нравится, но если вы пишете пользовательские html-помощники, вы хотите называть их так, как вы называете обычные html-помощники...)
И вы можете использовать asp.mvc, чтобы облегчить вашу жизнь:
public void MyMethod(object obj){
var dic=new System.Web.Routing.RouteValueDictionary(obj);
string param=dic["myparam"] as string;
}