System.Reflection 用法 [重复]

Posted

技术标签:

【中文标题】System.Reflection 用法 [重复]【英文标题】:System.Reflection Usage [duplicate] 【发布时间】:2014-02-14 00:33:23 【问题描述】:

我有课

class ABC

    Public int one = 10;
    Public String two = "123";
  public override string ToString()
   
   

我的问题是,我想在创建该类的对象时获取“ABC”类字符串中的字段信息/值。例如:

Public Class Test

    public static void Main()
    
        ABC a = new ABC();
        a.ToString();
    

现在我在这里创建一个“ABC”类的对象,然后我想重写 ToString() 的方法以获取字符串中 ABC 类的所有字段值。

作为解决方案,这对我有用:

**Here is an other solution if we use static fields and fieldsInfo:** 

class ReflectionTest

    public static int Height = 2;
    public static int Width = 10;
    public static int Weight = 12;
    public static string Name = "Got It";

    public override string ToString()
    
        string result = string.Empty;
        Type type = typeof(ReflectionTest); 
        FieldInfo[] fields = type.GetFields();
        foreach (var field in fields)
        
            string name = field.Name; 
            object temp = field.GetValue(null);
            result += "Name:" + name + ":" + temp.ToString() + System.Environment.NewLine;
        
        return result;
    


【问题讨论】:

为什么不直接覆盖ABC.ToString() 来返回你想要的? @Sean,手动返回“所需属性”不能很好地扩展。 @AndreiV - 谁说过要留住他们? @AndreiV 可以说每次都不是反射和连接字符串 @Sean,那我很困惑。他确实说他想覆盖ToString() 方法。有两种可能性:手动编写包含“属性名称/属性值”的“键/值”对或使用反射动态获取属性及其值。我错了吗?你想到了什么? 【参考方案1】:

如果我们使用静态字段和fieldInfo,这是另一种解决方案:

    class ReflectionTest

    public static int Height = 2;
    public static int Width = 10;
    public static int Weight = 12;
    public static string Name = "Got It";

    public override string ToString()
    
        string result = string.Empty;
        Type type = typeof(ReflectionTest); 
        FieldInfo[] fields = type.GetFields();
        foreach (var field in fields)
        
            string name = field.Name; 
            object temp = field.GetValue(null);
            result += "Name:" + name + ":" + temp.ToString() + System.Environment.NewLine;
        
        return result;
    


【讨论】:

【参考方案2】:

终于解决了我的问题:)

using System;
using System.Reflection;
using System.IO;
using System.Collections.Generic;
using System.Text;

class Program

    static void Main(string[] args)
    
        MyClass mC= new MyClass();
        string result = mC.ToString();
    


class MyClass

    string someValue = "One";
    int someValue1 = -1;
    bool someValue2 = false;
    float someValue3 = 2.2f;

    public string SomeValue
    
        get return this.someValue;
    

    public int SomeValue1
    
        get  return this.someValue1; 
    

    public bool SomeValue2
    
        get  return this.someValue2; 
    

    public float SomeValue3
    
        get  return this.someValue3; 
    

    public override string ToString()
    
        string result = string.Empty;
        Type type = this.GetType();
        PropertyInfo [] pInfo = type.GetProperties();

        for (int i = 0; i <= pInfo.Length-1; i++)
        
            Type internalType = this.GetType();
            PropertyInfo pInfoObject = internalType.GetProperty(pInfo[i].Name);
            object value = pInfoObject.GetValue(this,null);
            result += pInfo[i].Name + " : " + value.ToString() + System.Environment.NewLine;
        
        return result;
    

【讨论】:

【参考方案3】:

您可以使用以下两种方法中的任何一种来代替反射:

1:在这里你可以将你的类对象序列化为一个更易读的 JSON 对象:

    public override string ToString()
    

        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ABC));
        string str;
        using (MemoryStream stream = new MemoryStream())
        
            serializer.WriteObject(stream, this);
            stream.Position = 0;
            using (StreamReader streamReader = new StreamReader(stream, Encoding.UTF8))
            

                str = streamReader.ReadToEnd();
            
        

        return str;

2:在这里您可以将您的类对象序列化为 XML,这可以在其他地方使用:

    public override string ToString()
    

        XmlSerializer s = new XmlSerializer(typeof(ABC));
        StringBuilder sb = new StringBuilder();
        var xtw = XmlTextWriter.Create(sb);
        s.Serialize
            (xtw, this);

        return sb.ToString();

【讨论】:

【参考方案4】:

应该这样做:

public override string ToString() 
    string s = "";
    foreach(FieldInfo f in this.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)) 
        s += f.Name + "=" + f.GetValue(this).ToString() + "\r\n";
    
    return s;

BindingFlags.Public 仅反映公共成员。如果你也想要私人会员,也可以使用BindingFlags.Private 标志。 您可以在对象初始化时使用this.GetType().GetFields(),只调用一次。

这也适用于框架 2。 根据您的需要进行更改。

【讨论】:

【参考方案5】:

所以,这里是:

public class ABC
    
        public int one;
        public string two;
        public int three;

        public override string ToString()
        
            string names = String.Empty;
            System.Reflection.FieldInfo[] infos = this.GetType().GetFields();

            foreach (System.Reflection.MemberInfo inf in infos)
            
                if (names == String.Empty)
                
                    names = inf.Name;
                
                else
                
                    names += ';' + inf.Name;
                
            

            return names;
        
    

享受吧!

【讨论】:

【参考方案6】:

不确定是不是你的意思;

public override ToString() 

    return string.Format("one: 10two: 2", Environment.NewLine(), one, two);

【讨论】:

我认为他想要一种使用反射的通用方法。【参考方案7】:
public override string ToString()

    Dictionary<string, string> fieldValues = new Dictionary<string, string>();
    var fields = this.GetType().GetFields();

    foreach (var field in fields)
    
        fieldValues[field.Name] = field.GetValue(this).ToString();
    

    return string.Join(", ", fieldValues.Select(x => string.Format("0: 1", x.Key, x.Value)));

【讨论】:

FieldInfo 不会给我这个值,我可以从 propertyInfo 得到它【参考方案8】:

您可以使用属性来检索字符串,也可以覆盖ToString(),两者都会显示:

public class ABC

    private Int32 _one = 10;
    public Int32 One  get  return _one;  
    private String _two = "123";
    public String Two  get  return _two;  

    protected override ToString()
    
        return _two;
    

【讨论】:

我不认为问题是覆盖ToString。我认为问题是“如何使用反射枚举一个类的所有字段,然后从它们创建一个字符串。

以上是关于System.Reflection 用法 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

文本框绑定无法将“System.Reflection.RuntimeEventInfo”类型的对象转换为“System.Reflection.MethodInfo”类型

System.Reflection.Assembly 不包含“GetExecutingAssembly”的定义

System.Reflection.ExceptionHandlingClause.cs

System.Reflection.ParameterAttributes.cs

System.Reflection.LocalVariableInfo.cs

System.Reflection.CallingConvention.cs