从匿名类型获取值

本文关键字:获取 类型 | 更新日期: 2023-09-27 18:28:10

我有一个方法如下:

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'我使用不同的程序集,但这怎么可能呢?当我使用断点时,我可以看到我的动态areaobjectarea名称属性,我也可以看到它的值,但错误是:'object' does not contain a definition for 'area'我不知道这怎么可能?

编辑

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

从匿名类型获取值

使用这个:

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

如果您使用的是C#4:,那么您可以使用动态类型

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

但它确实引出了一个问题,即为什么不使用命名类型。匿名类型的设计并不是为了在这样的不同方法之间共享。

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

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

其次,如果你一心想做这件事,有很多方法可以做到。正如其他人所说,缓慢而危险的方法是使用动态。

快速而危险的方法是使用"示例投射":

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 });
}

有没有办法检查动态类型是否包含任何属性?

使用反射。当然,如果要使用"反射",则首先不需要使用动态。你使用动态来避免使用反射,所以如果你无论如何都要使用反射,你最好继续使用它。

听起来你正试图做一些在C#中很难做到的事情。我会重新评估你是否想这样做,如果你这样做了,C#是否适合你。像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;
}

另一种方法是将匿名数据转换为json,然后转换为c#json对象。用这种方法可以轻松读取所有数据。