Получить значение от анонимного типа

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

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

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

Ответ 1

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

string area = areaObject.GetType().GetProperty("area").GetValue(areaObject, null);

Ответ 2

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

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

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

EDIT: обратите внимание, что если это в другой сборке для исходного кода, создающего объект, вам нужно будет использовать [InternalsVisibleTo] поскольку анонимные типы являются внутренними.

Ответ 3

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

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

Быстро и опасно использовать "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, может быть лучше подходит для вашей задачи.

Ответ 4

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