有什么可以用来确定某个类型是否真的是匿名类型?例如一个界面等?
目标是创建类似以下的内容......
//defined like...
public static T Get<T>(this IAnonymous obj, string prop) {
return (T)obj.GetType().GetProperty(prop).GetValue(obj, null);
}
//...
//And then used like...
var something = new { name = "John", age = 25 };
int age = something.Get<int>("age");
或者这只是匿名类型的美丽?没有什么可以自我识别,因为它需要一个新的形状?
注意 - 我意识到您可以为对象类编写扩展方法,但在我看来,这看起来有点矫枉过正。
答案 0 :(得分:55)
编辑:以下列表适用于C#匿名类型。 VB.NET有不同的规则 - 特别是,它可以生成可变的匿名类型(默认情况下)。 Jared在评论中指出,命名风格也不同。基本上这都非常脆弱......
您无法在通用约束中识别它,但是:
object
但是规范保证这一点很少 - 所以它可以在下一版本的编译器中更改,或者如果你使用Mono等。
答案 1 :(得分:4)
我记得,有一个[CompilerGenerated]
标记...... 2秒
此外,该名称将是怪异的,并且它将是通用类型;-p
实际上,对于“获取”等,我可能只使用静态(非扩展)方法。
如果你只是想从anon-type的一个实例中获取值(在稍后的某个时间点),lambda可能是最好的选择 - 注意你需要一些技巧来解决这个问题:< / p>
static void Main()
{
var foo = new { name = "John", age = 25 };
var func = Get(foo, x => x.age);
var bar = new { name = "Marc", age = 30 };
int age = func(bar);
}
// template here is just for type inference...
static Func<TSource, TValue> Get<TSource, TValue>(
TSource template, Func<TSource, TValue> lambda)
{
return lambda;
}
(编辑评论)肯定是这个属性:
var foo = new { A = "B" };
Type type = foo.GetType();
CompilerGeneratedAttribute attrib = (CompilerGeneratedAttribute) Attribute.GetCustomAttribute(
type, typeof(CompilerGeneratedAttribute)); // non-null, therefore is compiler-generated
答案 2 :(得分:0)
出于扩展方法的目的,无法区分匿名类型。扩展方法通过为编译时可命名类型指定方法来工作。匿名类型是不可命名的,因此在编译时不可见。这使它们与扩展方法不兼容。