4

我有一个使用通用属性的类。例如:

class Person
{
    public MyGenericProperty<string> Field1
    {
        get { return field1; }
        set { field1 = value; }
    }

    private MyGenericProperty<string> field1= new MyInheritedGenericProperty<string>("Alan1");
}

我想在另一个类中使用这个类和反射,我有一个这样的方法

public void DoSomethingWithProperty(object sourceobject)
{
    foreach (var aProperty in sourceobject.GetType().GetProperties())
    {
        *if(aProperty.PropertyType == typeof(MyGenericProperty<>))*
        {
           *var obj = (MyGenericProperty<>)aProperty.GetValue(sourceobject, null);*
        }
    }
    return null;
}

我有两个问题

1- 如何对通用属性进行类型检查。在该示例代码中if(aProperty.PropertyType == typeof(MyGenericProperty<>))不起作用。

2- MyGenericProperty 的 T 可以是任何类,如何在不通过反射知道 T 的情况下将 MyGenericProperty 类转换为

var obj = (MyGenericProperty<>)aProperty.GetValue(sourceobject, null);

感谢您的帮助。

4

1 回答 1

9

首先,重要的是要了解您没有“通用属性” - 没有这样的东西。你有一个类型是泛型类型的属性......这不是一回事。(将其与泛型类型或泛型方法进行比较,就引入新的类型参数而言,它们中的每一个都是真正的泛型。)

您可以使用以下代码对其进行测试:

if (aProperty.PropertyType.IsGenericType &&
    aProperty.GetGenericTypeDefinition() == typeof(MyGenericProperty<>))

但至于铸造 - 这取决于你想对之后的价值做什么。您可能想要声明一个MyGenericProperty<>包含所有不依赖于类型参数的成员的非泛型基类型。我通常会给出与泛型类型相同的名称(例如MyGenericProperty),只是不给它类型参数。然后,如果您只需要其中一个成员,则可以使用:

if (aProperty.PropertyType.IsGenericType &&
    aProperty.GetGenericTypeDefinition() == typeof(MyGenericProperty<>))
{
    var value = (MyGenericProperty) aProperty.GetValue(sourceObject, null);
    // Use value
}

但是在那种情况下,您仍然可以使用Type.IsAssignableFrom

if (typeof(MyGenericProperty).IsAssignableFrom(aProperty.PropertyType))
{
    var value = (MyGenericProperty) aProperty.GetValue(sourceObject, null);
    // Use value
}

如果这些提示对您没有帮助,请详细说明您正在尝试做什么。

于 2013-08-24T15:44:44.907 回答