只要我在与Program
类相同的程序集中有ClassSameAssembly
类,下面的代码就可以很好地工作。但是,当我将类ClassSameAssembly
移动到单独的程序集中时,抛出了一个RuntimeBinderException
(如下所示)。有可能解决这个问题吗?
using System;
namespace ConsoleApplication2
{
public static class ClassSameAssembly
{
public static dynamic GetValues()
{
return new
{
Name = "Michael", Age = 20
};
}
}
internal class Program
{
private static void Main(string[] args)
{
var d = ClassSameAssembly.GetValues();
Console.WriteLine("{0} is {1} years old", d.Name, d.Age);
}
}
}
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
:‘’不包含‘Name’的定义
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at ConsoleApplication2.Program.Main(String[] args) in C:\temp\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 23
发布于 2010-04-13 22:42:17
我认为问题在于匿名类型是作为internal
生成的,因此绑定器并不真正“知道”它本身。
尝试使用ExpandoObject:
public static dynamic GetValues()
{
dynamic expando = new ExpandoObject();
expando.Name = "Michael";
expando.Age = 20;
return expando;
}
我知道这有点丑陋,但这是目前我能想到的最好的……我认为你甚至不能对它使用对象初始化器,因为尽管它被强类型化为ExpandoObject
,但编译器不知道如何处理"Name“和"Age”。您可以执行以下操作:
dynamic expando = new ExpandoObject()
{
{ "Name", "Michael" },
{ "Age", 20 }
};
return expando;
但这也好不到哪里去。
您可能会编写一个扩展方法,通过反射将匿名类型转换为具有相同内容的扩展。然后你可以这样写:
return new { Name = "Michael", Age = 20 }.ToExpando();
这真是太可怕了:
发布于 2010-08-18 20:24:40
您可以使用[assembly: InternalsVisibleTo("YourAssemblyName")]
使您的程序集内部可见。
发布于 2011-01-04 21:18:29
我遇到了一个类似的问题,我想补充说Jon Skeets回答说还有另一个选择。我发现的原因是我意识到Asp MVC3中的许多扩展方法都使用匿名类作为输入来提供html属性(新的{alt="Image alt",style=“padding: 5px"} =>
无论如何,这些函数使用RouteValueDictionary类的构造函数。我自己试过了,它确实有效--尽管只有第一层(我使用的是多层结构)。因此-在代码中,这将是:
object o = new {
name = "theName",
props = new {
p1 = "prop1",
p2 = "prop2"
}
}
SeparateAssembly.TextFunc(o)
//In SeparateAssembly:
public void TextFunc(Object o) {
var rvd = new RouteValueDictionary(o);
//Does not work:
Console.WriteLine(o.name);
Console.WriteLine(o.props.p1);
//DOES work!
Console.WriteLine(rvd["name"]);
//Does not work
Console.WriteLine(rvd["props"].p1);
Console.WriteLine(rvd["props"]["p1"]);
所以..。这到底是怎么回事?在RouteValueDictionary内部可以看到以下代码(上面的值为~= o):
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
object obj2 = descriptor.GetValue(values);
//"this.Add" would of course need to be adapted
this.Add(descriptor.Name, obj2);
}
所以-使用TypeDescriptor.GetProperties(o)我们将能够获得属性和值,尽管匿名类型在单独的程序集中被构造为内部类型!当然,这很容易扩展,使其成为递归。如果你愿意,还可以做一个扩展方法。
希望这能有所帮助!
/Victor
https://stackoverflow.com/questions/2630370
复制相似问题