【问题标题】:Why reflection does not find property为什么反射找不到属性
【发布时间】:2013-01-16 09:25:42
【问题描述】:

我有课:

    class Person 
    {
        public string Name { get { return "Antonio"; } }
    }

和代码:

        IEnumerable<object> uncknownObject;

        uncknownObject = new ObservableCollection<Person>( );

        var observCol = uncknownObject.GetType( );

        var x = ( ( dynamic )observCol ).GenericTypeArguments[ 0 ];

        var y = observCol.GetProperty( "GenericTypeArguments" );

        var instance = ( Person )Activator.CreateInstance( x );

        Console.WriteLine( instance.Name ); // Print Antonio!!!

为什么y == null

注意图片:

调试器显示属性 GenericTypeArguments 应该存在并且代码显示了相反的位置。可以证明调试器是正确的并且该属性存在,因为 x 怎么不为空。如果该属性存在,那么为什么y 等于 null!!!???


编辑

感谢 Ani,我现在有了:

        IEnumerable<object> uncknownObject;

        uncknownObject = new ObservableCollection<Person>();

        var observCol = uncknownObject.GetType();

        var genTypeArgsProperty = typeof(Type).GetProperty("UnderlyingSystemType");

        var genTypeArgsValue = (genTypeArgsProperty.GetValue(observCol, null));

        var f = genTypeArgsValue.GetType().GetMethod("GetGenericArguments");

        IEnumerable<object> result = (IEnumerable<object>)f.Invoke(genTypeArgsValue, null);

        var x = result.FirstOrDefault();

        var instance = Activator.CreateInstance(  (Type)x );

In case of curios why I needed that functionality click here

【问题讨论】:

  • 那是 VS 2010 吗? GenericTypeArguments 直到 .Net 4.5 才存在。
  • @mikez:那么它是如何出现在调试器中的???
  • @leppie 我不知道,但根据文档,它是在 .NET 4.5 中添加的(支持的框架只有 .NET 4.5):msdn.microsoft.com/en-us/library/…
  • @mikez:我只能假设,即使安装了 .NET 4.5,即使使用 VS2010。

标签: c# dynamic reflection


【解决方案1】:

我不太明白你想通过所有这些元元反射来完成什么,但你似乎误解了 Type.GetProperty 的作用。它获取由System.Type 实例(在本例中为ObservableCollection&lt;Person&gt;)表示的实际 类型的属性的元数据。它确实获取在System.Type 本身上声明的属性的元数据,当然除非您在代表System.Type 本身的System.Type 上调用它。

在您的情况下,y 为 null,因为 ObservableCollection&lt;Person&gt; 没有名为“GenericTypeArguments”的属性。

试试这个:

var genTypeArgsProperty = typeof(Type).GetProperty("GenericTypeArguments");

var genTypeArgsValue = (Type[]) (genTypeArgsProperty.GetValue(observCol, null));

var onlyTypeArgValue = genTypeArgsValue.Single();

【讨论】:

  • var observCol = uncknownObject.GetType( ); 所以是的,它是一个类型,不是吗?
  • 但是出于 OP 的目的,这种类型需要代表 System.Type。这都是非常元的。 :)
  • 哇,我正要尝试它,但在这台计算机上我什至没有获得 GenericTypeArguments 属性。换句话说,现在我的程序崩溃了,而在另一台计算机上它运行良好。这很奇怪。感谢您的帮助!
  • 这可能是因为 GenericTypeArguments 属性是 .NET 4.5 的新属性。在以前的版本中,您必须使用 GetGenericArguments 方法。
  • 阿尼非常感谢!最后一个问题......那么我在调试器上看到的所有属性是什么?我如何判断天气这些属性是否来自实际类型?我仍然无法理解属性 GenericTypeArguments 的来源。
【解决方案2】:

此代码适用于 net framework 4:

        IEnumerable<object> uncknownObject;

        uncknownObject = new ObservableCollection<Person>();



        var observCol = uncknownObject.GetType();

        var x = ((dynamic) observCol).UnderlyingSystemType.GetGenericArguments()[0];

        var y = observCol.GetGenericArguments();

        var instance = (Person)Activator.CreateInstance(x);

        Console.WriteLine(instance.Name); // Print Antonio!!!

【讨论】:

  • 修复获取 y。 observCol.GetMethod("GetGenericArguments", Type.EmptyTypes) 返回 null。所以可能是扩展方法
  • +1 感谢您的回答,现在我切换到 .net 4.0 计算机后,我可以让 Ani 的答案正常工作。
猜你喜欢
  • 2012-06-13
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多