从设置的对象中获取字段

时间:2013-10-26 05:20:10

标签: c# generics reflection

我有以下结构:

 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,但我不知道泛型的类型。基本上我正在寻找的是:获取类型为UserProp的MyClass的所有字段(无论泛型类型),其中IsSet为真。

3 个答案:

答案 0 :(得分: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类型,并且可以在强制转换后直接访问值(而不是再按一次反射来获取值)。

答案 1 :(得分:3)

如果你不介意使用动态关键字,那么这应该有效:

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();
    }

答案 2 :(得分: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