从匿名类型中获取价值

时间:2012-03-17 12:44:55

标签: c# asp.net-mvc asp.net-mvc-3 c#-4.0 anonymous-types

我有一个方法如下:

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

这是HtmlHelper定义的AssemblyInfo:

[assembly: AssemblyTitle("MyProject.Presentation")]
[assembly: InternalsVisibleTo("cpanel.MyProject.dev")]

但还有错误:'object' does not contain a definition for 'area' 我使用不同的程序集,但是如何可能,当我使用断点时,我可以看到我的动态areaobject具有area name属性,而且我可以看到它的值,但错误说:{{ 1}}我无法弄清楚它是如何实现的?

修改

我更改了程序集,现在动态类型是内部的,但错误仍然像以前一样

4 个答案:

答案 0 :(得分:24)

使用这个:

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

答案 1 :(得分:20)

好吧,如果您使用的是C#4,则可以使用动态类型:

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

它确实提出了为什么你没有使用命名类型的问题。匿名类型并非真正设计为在这样的不同方法之间共享。

编辑:请注意,如果这与创建对象的原始代码位于不同的程序集中,则您需要使用[InternalsVisibleTo],因为匿名类型是内部的。

答案 2 :(得分:6)

首先,正如其他人所说:首先不要这样做。这不是如何使用匿名类型。

其次,如果您愿意这样做,有很多方法可以做到。正如其他人所说,缓慢而危险的方式是使用动态。

快速而危险的方法是使用“按示例施放:

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,那么就不需要首先使用动态。你使用dynamic来避免使用Reflection ,所以如果你打算继续使用Reflection,你也可以继续使用它。

听起来你正在尝试做一些C#中难以做到的事情。我会重新评估你是否想要这样做,如果你这样做,C#是否适合你。像IronPython这样的动态语言可能更适合您的任务。

答案 3 :(得分:1)

每个人都说'#34;不要在第一时间做到这一点&#34;,但这正是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;
}