从匿名类型获取值
本文关键字:获取 类型 | 更新日期: 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'
我使用不同的程序集,但这怎么可能呢?当我使用断点时,我可以看到我的动态areaobject
有area
名称属性,我也可以看到它的值,但错误是:'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对象。用这种方法可以轻松读取所有数据。