在C#中使用反射在运行时获取类实例的属性

5

您好,这是我试图完成的任务:我有一个类(EventType),这个类可能是动态的,不同的时间具有不同的成员/属性。

class EventType
{
    int id{set;}
    string name{set;}
    DateTime date{set;}
    List<int> list{set;}
    Guid guid{set;}
}

在我的主方法中,我将这个类的实例传递给不同类中的一个函数,并尝试使用反射来获取实例的属性,但是没有成功,并返回了null值。
class Program
{
    static void Main(string[] args)
    {
        EventType event1 = new EventType();
        int rate = 100;
        DataGenerator.Generate<EventType>(event1, rate);
    }
    public static byte[] test(EventType newEvent)
    {
        return new byte[1];
    }
}



static class DataGenerator
{
    public static void Generate<T>(T input, int eventRate, Func<T, byte[]> serializer=null)
    {            
        Type t = input.GetType();
        PropertyInfo[] properties = t.GetProperties();
        foreach (PropertyInfo property in properties)
        {
            Console.WriteLine(property.ToString());   
        }
        var bytes = serializer(input);
    }
}

关于你的“生成”方法,我想知道它与开箱即用的序列化有何不同?(二进制序列化、XML序列化或JSon)。难道你不应该依赖现有的序列化机制吗? - Steve B
我正在尝试使该方法能够让人们使用自己的序列化程序,如果他们没有提供一个,那么我将继续使用现有的序列化程序之一。 - MJSHARMA
4个回答

5
你的类属性默认是私有的,而GetProperties仅返回公共属性。
要么将属性提升为公共属性:
class EventType
{
    public int id{set;}
    public string name{set;}
    public DateTime date{set;}
    public List<int> list{set;}
    public Guid guid{set;}
}

或者指定绑定标志获取非公开属性:
Type t = input.GetType();
PropertyInfo[] properties = t.GetProperties(
    BindingFlags.NonPublic | // Include protected and private properties
    BindingFlags.Public | // Also include public properties
    BindingFlags.Instance // Specify to retrieve non static properties
    );

@peter 感谢您的帮助,如果我使用字段而不是属性会怎样呢?codeclass EventType { int id; string name; DateTime date; List<int> list; Guid guid; } code - MJSHARMA
GetFields替换GetProperties - Steve B

2

Type.GetProperties 返回所有 公有 属性,在您的类中它们都是私有的,因此不会被返回。您可以将它们改为公有或使用 BindingFlags 搜索私有属性,例如:

t.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);

2
Type.GetProperties 方法返回类型的公共属性。但是,如果您没有指定属性的访问类型,则它们默认为私有
您可以使用重载的Type.GetProperties(BindingFlags) 方法获取所有属性,而不考虑其访问修饰符。请注意保留HTML标签。

1
class EventType
{
    int id { get; set; }
    string name { get; set; }
    DateTime date { get;  set; }
    List<int> list { get; set; }
    Guid guid { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        EventType event1 = new EventType();
        int rate = 100;
        DataGenerator.Generate<EventType>(event1, rate);
    }
    public static byte[] test(EventType newEvent)
    {
        return new byte[1];
    }
}



static class DataGenerator
{
    public static void Generate<T>(T input, int eventRate, Func<T, byte[]> serializer = null)
    {
        Type t = input.GetType();
        PropertyInfo[] properties = t.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
        foreach (PropertyInfo property in properties)
        {
            Console.WriteLine(property.ToString());
        }
        //var bytes = serializer(input);
    }
}

感谢您的帮助,如果我使用字段而不是属性会怎样呢? 类 EventType { int id; string name; DateTime date; List<int> list; Guid guid; } - MJSHARMA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接