【问题标题】:Reflection in C# -- want a list of the data types of a class' fieldsC# 中的反射——想要一个类字段的数据类型列表
【发布时间】:2009-07-09 14:04:35
【问题描述】:

我的 C# 类 MyClass(如下)有成员 a、b、c、d、e 和 f。

我想使用反射来获取这些成员的数据类型列表; 例如(借用 Python 表示法):[ char[], ushort, char, byte, uint, ulong ]。

class MyClass
{
    public  char [ ]    a ;
    public  ushort      b ;
    public  char        c ;
    public  byte        d ;
    public  uint        e ;
    public  ulong       f ;
}

class MainClass
{
public static void Main ( string [] args )
    {
        // get an array (or some kind of list) of MyClass' fields' data types ...
        // for example:  { char[], ushort, char, byte, uint, ulong }

        // I've tried the following, but can't get a column of just the data types, alone ...
        MemberInfo[] theMemberInfoArray = typeof(MyClass).GetMembers() ;
        foreach (MemberInfo mi in theMemberInfoArray)
            if (mi.MemberType == MemberTypes.Field)
                    Console.WriteLine ( "<" + mi.MemberType + ">\t"
                    + "<" + mi.GetType() + ">\t"
                    + "<" + mi.Name + ">\t" + mi ) ;
    }

}

程序输出如下:

<Field> <System.Reflection.RtFieldInfo> <a>     Char[]  a
<Field> <System.Reflection.RtFieldInfo> <b>     UInt16  b
<Field> <System.Reflection.RtFieldInfo> <c>     Char    c
<Field> <System.Reflection.RtFieldInfo> <d>     Byte    d
<Field> <System.Reflection.RtFieldInfo> <e>     UInt32  e
<Field> <System.Reflection.RtFieldInfo> <f>     UInt64  f

我希望程序输出显示为:

<Field> <System.Reflection.RtFieldInfo> <a>     <Char[]>     Char[] a
<Field> <System.Reflection.RtFieldInfo> <b>     <UInt16>     UInt16 b
<Field> <System.Reflection.RtFieldInfo> <c>     <Char>       Char   c
<Field> <System.Reflection.RtFieldInfo> <d>     <Byte>       Byte   d
<Field> <System.Reflection.RtFieldInfo> <e>     <UInt32>     UInt32 e
<Field> <System.Reflection.RtFieldInfo> <f>     <UInt64>     UInt64 f

【问题讨论】:

  • 在您的帖子中,实际输出和您所说的希望输出是相同的。我假设您想要的不是您发布的内容,因此请编辑您的问题以澄清您想要的输出实际是什么。
  • 您必须缩进四位以保持格式。我已经为你做了。顺便说一句,这叫做“反思”,而不是“内省”。
  • 我不明白这两个输出之间的区别。所需的输出只是重复没有尖括号的第 4 列。

标签: c# reflection types field


【解决方案1】:

我就是这样做的,你想要一个实际返回 Type 实例的 FieldType。

var members = typeof(TestMe).GetFields().Select(m => new 
                                         { 
                                             Name = m.Name, 
                                             MemType = m.MemberType, 
                                             RtField = m.GetType(), 
                                             Type = m.FieldType 
                                         });

foreach (var item in members)
    Console.WriteLine("<{0}> <{1}> <{2}> <{3}> {3} {2}", item.MemType, item.RtField, item.Name, item.Type, item.Type, item.Name);

public class TestMe
{
    public string A;
    public int B;
    public byte C;
    public decimal D;
}

这是输出:

<Field> <System.Reflection.RtFieldInfo> <A> <System.String> System.String A 
<Field> <System.Reflection.RtFieldInfo> <B> <System.Int32> System.Int32 B
<Field> <System.Reflection.RtFieldInfo> <C> <System.Byte> System.Byte C
<Field> <System.Reflection.RtFieldInfo> <D> <System.Decimal> System.Decimal D

【讨论】:

  • 感谢您的这个想法。我不得不对其进行一些修改以使其适合我,但这个想法来自你——再次感谢。 FieldInfo [ ] fieldInfoArray = typeof(MyClass).GetFields() ; List fieldTypeList = new List ( ) ; foreach(fieldInfoArray 中的 FieldInfo fieldInfo) fieldTypeList.Add(fieldInfo.FieldType); foreach ( System.Type type in fieldTypeList ) Console.WriteLine ( type ) ;
  • 没问题。顺便说一句,如果你只是想要一个列表。您可以像这样在 Linq 中使用 .ToList() 方法: List list = typeof(TestMe).GetFields().Select(m => m.FieldType).ToList();
【解决方案2】:

我不确定 MemberInfo 是否有您想要的信息。您可能想查看GetFields()FieldInfo 类,或GetProperties()PropertyInfo 类。

GetMembers() 返回所有字段、属性和方法,因此如果您的类包含这些,它们也会被枚举。

【讨论】:

    【解决方案3】:

    您正在寻找 FieldType 的 Name 属性,该属性可通过 FieldInfo 获得。您需要先将 MemberInfo 转换为 FieldInfo:

    foreach (MemberInfo mi in theMemberInfoArray)
    {
        if (mi.MemberType == MemberTypes.Field)
        {
            FieldInfo fi = mi as FieldInfo;
            Console.WriteLine(fi.FieldType.Name);
        }
    }          
    

    输出:

    Char[]
    UInt16
    Char
    Byte
    UInt32
    UInt64
    

    【讨论】:

    • 谢谢!我希望我能接受多个答案,因为你的想法也是一个好主意。
    【解决方案4】:

    mi.Name 正在带回你想要的,你只需要更改你的 COnsole.WriteLine 以再次打印它

    【讨论】:

    • 我怀疑你可能误解了我的意思。我想要datatypes 的列表,而不是字段名称。例如,我想要一个列表 [ char[], ushort, char, byte, uint, ulong ],一个我可以以编程方式使用的列表,而不仅仅是显示在屏幕上。
    • 因此,在将它们写入控制台的循环中,使用 Type.GetType(mi.Name) 将类型添加到 List
    • 对不起,你想要 mi.GetType() 而不是 mi.Name
    • mi.GetType() 返回 System.Reflection.RtFieldInfo 不是字段的实际类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2017-11-21
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 2010-12-20
    • 2017-11-28
    相关资源
    最近更新 更多