将函数应用于类中的每个字段

时间:2012-04-22 03:06:27

标签: c#

这是一个有趣的概念,我无法弄清楚如何实施。 (它与大学任务有关,我需要部署装饰模式)。

我在下面写了粗略的C#代码然后无法编译,假设,我有一个类

Class A {
   public int A { get; set; }
   public string B { get; set; }
   public float C { get; set; }

   public string concatFields() {
       string sample = null;
       foreach (Field f in this) {
           sample += f.ToString();
       }
       return sample;
   }
}

如何实现concatFields方法?有没有办法迭代类的字段(不知道字段的名称)并在每个字段上调用ToString()。

在示例B场景中,如果它们是相同的类型,您将如何在所有字段上应用相同的方法。

欢呼大家帮忙,我用C#标记了这个,但不确定可以应用其他标签

4 个答案:

答案 0 :(得分:1)

您可以使用reflection,迭代您的类的元数据,并通过反射API提取字段。显然,有一个成本附加:使用反射比直接访问字段慢;有时,相当。但是,你当然可以做到。这是一个例子:

MyClass obj = new MyClass();
// Set fields in the obj...
var fields = typeof(MyClass).GetFields(System.Reflection.BindingFlags.GetField);
StringBuilder res = new StringBuilder();
foreach (FieldInfo f in fields) {
    var val = f.GetValue(obj);
    if (val != null) res.Append(val.ToString());
}
Console.WriteLine(res.ToString());

FieldInfo类公开了许多有用的属性,例如NameType,让您选择要在处理中包含的字段以及要忽略的字段。

答案 1 :(得分:0)

将“字段”放入字典中。

以下是如何迭代字典:What is the best way to iterate over a Dictionary in C#?

答案 2 :(得分:0)

对于.NET / C#,类型内省是通过System.Reflection命名空间处理的。这允许您检索有关类型的信息,并动态调用编译时未知的方法。

  

如何实现concatFields方法?有没有办法迭代类的字段(不知道字段的名称)并在每个字段上调用ToString()。

public string concatFields() {
   string sample = null; // a StringBuilder would be a better choice here
   foreach (FieldInfo f in this.GetType().GetFields()) {
       obj fieldValue = f.GetValue();
       if (fieldValue != null) sample += fieldValue.ToString();
   }
   return sample;
}
  

在示例B场景中,如果它们是相同的类型,您将如何在所有字段上应用相同的方法。

如果您在编译时知道类型,可以转换为它:

foreach (FieldInfo f in this.GetType().GetFields()) {
    MyType myType = (MyType)f.GetValue();
    myType.MyMethod();
}

或者,您可以通过反射动态调用:

foreach (FieldInfo f in this.GetType().GetFields()) {
    object fieldValue = f.GetValue();
    MethodInfo mi = fieldValue.GetType().GetMethod("MyMethod");
    mi.Invoke(fieldValue, null); // no parameters to MyMethod
}

答案 3 :(得分:0)

这就是我要这样做的方式:

class A

{
    public int A { get; set; }
    public string B { get; set; }
    public float C { get; set; }

    public string[] concatFields()
    {
        var v = from f in this.GetType().GetFields() select f;
        IList<string> fields = new List<string>();
        foreach (var f in v)
        {
            fields.Add(f.GetValue(this).ToString());
        }
        return fields.ToArray<string>();
    }
}