0

我有以下结构:

 public struct UserProp<T>
{
    private T val;
    public string Name { get; set; }

    public T Value
    {
        get
        {
            return (T) this.val;
        }
        set
        {
            this.val= value;
            this.IsSet = true;
        }
    }

    public bool IsSet;


}

和一个使用它的类:

public class MyClass
{
     private UserProp<string> FirstName;
     private UserProp<int> ID;
     ....
}

如何获取 IsSet 为 true 的对象的所有字段?我打算使用反射并将 GetField 值转换为 UserProp,但我不知道泛型的类型。基本上我正在寻找的是:获取 MyClass 类型的 UserProp (无论泛型类型)的所有字段,其中 IsSet 为真。

4

3 回答 3

3

如果您不介意使用 dynamic 关键字,这应该可以工作:

static void Main(string[] args)
    {
        MyClass myclass = new MyClass();
        var type = myclass.GetType();
        var fields = type.GetFields().Where(x => x.FieldType != null && x.FieldType.Name == "UserProp`1");

        foreach (var item in fields)
        {
            dynamic userProp = item.GetValue(myclass);
            Console.WriteLine(userProp.IsSet);
        }

        myclass.FirstName.Value = "Mark";

        foreach (var item in fields)
        {
            dynamic userProp = item.GetValue(myclass);
            Console.WriteLine(userProp.IsSet);
        }

        Console.ReadLine();
    }
于 2013-10-26T07:18:58.787 回答
3

除非您有充分的理由使用,否则请struct考虑切换到class您的UserProp. 比您可以拥有用于共享属性的基类:

public class UserProp
{
   public string Name { get; set; }
   public bool IsSet { get; set; }
}

public class UserProp<T> : UserProp
{
   private T val;
   public T Value...
}

这样,您只需要在字段上进行反射并检查已知UserProp类型和值,在转换后可以直接访问(而不是再一次反射以通过名称获取值)。

于 2013-10-26T07:06:27.323 回答
2

但我不知道泛型的类型

你不需要知道是什么T。使用开放的泛型类型。这是一个希望正确的例子:

var myClass = new MyClass();

foreach (var fieldInfo in myClass.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
    var fieldType = fieldInfo.FieldType;

    if (!fieldType.IsGenericType ||
        fieldType.GetGenericTypeDefinition() != typeof (UserProp<>))
    {
        Console.WriteLine("Ignoring {0} {1}", fieldType.Name, fieldInfo.Name);
        continue;
    }

    var fieldValue1 = fieldInfo.GetValue(myClass);
    var fieldInfo2 = fieldValue1.GetType().GetField("IsSet");
    var fieldValue2 = fieldInfo2.GetValue(fieldValue1);

    Console.WriteLine("{0}.IsSet has a value of {1}", fieldInfo.Name, fieldValue2);

    // You can check fieldValue2 and if true you now have "[a field] of
    // MyClass of type UserProp (regardless of generic type) where IsSet
    // is true". Loop until you get them all!
}

鉴于以下定义MyClass

public class MyClass
{
    private int z;
    private UserProp<string> FirstName;
    private UserProp<int> ID;

    public MyClass()
    {
        ID.Value = 5;
    }
}

会产生这个结果:

Ignoring Int32 z
FirstName.IsSet has a value of False
ID.IsSet has a value of True
于 2013-10-26T09:55:53.763 回答