【问题标题】:System.Reflection Usage [duplicate]System.Reflection 用法 [重复]
【发布时间】: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() 方法。有两种可能性:手动编写包含“属性名称/属性值”的“键/值”对或使用反射动态获取属性及其值。我错了吗?你想到了什么?

标签: c# reflection


【解决方案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: {1}{0}two: {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。我认为问题是“如何使用反射枚举一个类的所有字段,然后从它们创建一个字符串。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-02-27
            • 1970-01-01
            • 2011-06-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-29
            相关资源
            最近更新 更多