Получить значение от анонимного типа - PullRequest
13 голосов
/ 17 марта 2012

У меня есть следующий метод:

public void MyMethod(object obj){

  // implement

}

И я называю его так:

MyMethod(new { myparam= "waoww"});

Так как же мне реализовать MyMethod(), чтобы получить значение myparam?

Редактировать

Я использую это:

dynamic d= obj; 
string param = d.myparam; 

но ошибка увеличивается:

'object' does not contain a definition for 'myparam' 

также я использую точку останова и ясм. d, имеют свойство строки myparam.

И есть ли способ проверить динамический тип, если он содержит какое-либо свойство, подобное этому:

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 есть area имя свойства, а также я вижу его значение, но ошибка говорит: 'object' does not contain a definition for 'area' Я не могу понять, как это возможно?

Редактировать

Я изменяю сборку, и теперь динамический тип является внутренним, но ошибка остается, как и раньше

Ответы [ 4 ]

24 голосов
/ 18 марта 2012

Используйте это:

string area = areaObject.GetType().GetProperty("area").GetValue(areaObject, null);
21 голосов
/ 17 марта 2012

Ну, вы могли бы использовать динамическую типизацию, если вы используете C # 4:

public void MyMethod(object obj) {
    dynamic d = obj;
    Console.WriteLine(d.myparam);
}

Однако возникает вопрос, почему вы не используете именованный тип.Анонимные типы на самом деле не предназначены для совместного использования разными методами, такими как этот.

РЕДАКТИРОВАТЬ: обратите внимание, что если он находится в сборке, отличной от исходного кода, создающего объект, вам необходимо использовать [InternalsVisibleTo], поскольку анонимные типы являются внутренними.

6 голосов
/ 17 марта 2012

Во-первых, как уже говорили другие: не делайте этого в первую очередь.Это не то, как анонимные типы предназначались для использования.

Во-вторых, если вы стремитесь сделать это, есть несколько способов сделать это.Медленный и опасный способ - использовать динамический, как уже говорили другие.

Быстрый и опасный способ - использовать «приведение примера»:

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, вы можете просто продолжать его использовать.

Звучит так, как будто вы пытаетесь это сделатьчто-то, что трудно сделать в C #. Я бы переоценил, хотите ли вы это делать, и если вы это сделаете, то является ли C # языком для вас. Динамический язык, такой как IronPython, может лучше подойти для вашей задачи.

1 голос
/ 14 февраля 2013

Все говорят "не делай этого в первую очередь", но это именно то, что делает 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;
}
...