【问题标题】:Getting Types of all members of a class获取类的所有成员的类型
【发布时间】:2017-06-15 14:23:20
【问题描述】:

我需要获取类中所有成员的类型。

    public class Order
    {
        public int OrderID { get; set; }
        public int EmployeeID { get; set; }
        public string CustomerID { get; set; }
        public DateTime OrderDate { get; set; }
        public bool Verified { get; set; }

        public Order(int orderId, int empId, string custId, DateTime orderDate, bool verify)
        {
            this.OrderID = orderId;
            this.EmployeeID = empId;
            this.CustomerID = custId;
            this.OrderDate = orderDate;
            this.Verified = verify;
        }
    }   

以及我通过 List 添加的类的值

            List<dynamic> dy = new List<dynamic>();
            dy.Add(new { OrderID = 11, EmployeeID = 5, CustomerID = "ALFKI", OrderDate = new DateTime(2015,01, 10), Verified = true });
            dy.Add(new { OrderID = 12, EmployeeID = 4, CustomerID = "CDSAW", OrderDate = new DateTime(2015, 02, 12), Verified = true });
            dy.Add(new { OrderID = 13, EmployeeID = 6, CustomerID = "ASDFG", OrderDate = new DateTime(2015, 03, 13), Verified = true });
            dy.Add(new { OrderID = 14, EmployeeID = 3, CustomerID = "XSDAF", OrderDate = new DateTime(2015, 04, 14), Verified = false });
            dy.Add(new { OrderID = 15, EmployeeID = 2, CustomerID = "MNHSD", OrderDate = new DateTime(2015, 05, 15), Verified = true });
            dy.Add(new { OrderID = 16, EmployeeID = 1, CustomerID = "OKJHG", OrderDate = new DateTime(2015, 06, 16), Verified = false });
            return dy;

为了获取字段类型,我尝试了以下代码。

Type type = dataSource.GetElementType();
Type t = typeof(object);
t = type.GetProperty("OrderDate").PropertyType;

它会引发空表达式错误。

这里的 OrderDate 是 DateTime 对象。

Type type = dataSource.GetType(); 

这一行,返回 System.object。

尝试获取 OrderDate 字段类型时。

type.GetProperty(filterString).PropertyType;

返回 Null,如何解决此问题。

在线:https://dotnetfiddle.net/zTYJGU

【问题讨论】:

  • 你的意思是像这里描述的那样? stackoverflow.com/questions/6536163/…
  • 这看起来像是对dynamic的不当使用...
  • 你能定义什么是dataSource吗?
  • 嗨 Matthew Watson,为了方便起见,我在 List 中使用了动态关键字。不要考虑那个,我的要求是获取Class中字段的类型。这里dataSource指的是包含Order类记录的dy列表

标签: c# generics member system.type


【解决方案1】:

首先,如果你想获取指定类型的所有字段和属性类型,你应该知道一些事情。

每个属性都有自己的支持字段。对于自动生成的属性public int MeProperty { get; set; },支持字段将具有名称&lt;MeProperty&gt;k__BackingField

了解这一点后,您应该考虑提取 FieldInfo 而不是 PropertyInfo

另一件事是您假设GetProperty 方法甚至会提取隐藏的(privateprotected 等)成员,这是完全错误的。它希望您使用 BindingFlags 枚举指定可访问性级别。

获得所有这些知识后,您可以使用以下方法提取所有字段而不是属性:

var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

之后你可以枚举和获取字段类型:

var fieldTypes = fields.Select(f => f.FieldType);

现在您的fieldTypesIEnumerable&lt;Type&gt;,包含type 字段中指定的每个字段类型。

真正的问题是你想实现自动映射器,它从动态类型创建你定义的类型。为此,我建议您使用来自my answer on this question的解决方案

编辑:

使用此代码:

class Program
{
    static void Main()
    {
        foreach(var field in typeof(Order).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
        {
            Console.WriteLine(field.Name);
        }
    }

    public class Order
    {
        public int OrderID { get; set; }
        public int EmployeeID { get; set; }
        public string CustomerID { get; set; }
        public DateTime OrderDate { get; set; }
        public bool Verified { get; set; }

        public Order(int orderId, int empId, string custId, DateTime orderDate, bool verify)
        {
            this.OrderID = orderId;
            this.EmployeeID = empId;
            this.CustomerID = custId;
            this.OrderDate = orderDate;
            this.Verified = verify;
        }
    }
}

你应该有相同的输出:

<OrderID>k__BackingField                                                                                                                                                                                                                               
<EmployeeID>k__BackingField                                                                                                                                                                                                                            
<CustomerID>k__BackingField                                                                                                                                                                                                                            
<OrderDate>k__BackingField                                                                                                                                                                                                                             
<Verified>k__BackingField 

【讨论】:

  • 您好 Rogalsi,我尝试了您的解决方案。但我只得到三个字段而不是所有字段
猜你喜欢
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 2018-10-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
相关资源
最近更新 更多