0

This is an interesting concept which i couldn't figure out how to implement. (its related to a university assignment where i need to deploy the decorator pattern).

I've written rough C# code below which won't compile however, Suppose, i have a class

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;
   }
}

How in terms would you achieve the concatFields method? Is there a way to iterate through the class's fields (without knowing the names of the fields) and call ToString() on each.

In example B scenario, how would you apply the same method on all Fields provided they were the same type.

Cheers guys for the help, i've tagged this with C# but not sure what other tags could be applied

Abstract
  • 455
  • 1
  • 3
  • 12
  • 1
    The concept you are looking for is called "Reflection" – J. Holmes Apr 22 '12 at 03:13
  • Please check out this example on [dotnetpearls](http://www.dotnetperls.com/reflection-field) it gives a pretty straightforward example (with code) of doing exactly what you are asking for using reflection. – vpiTriumph Apr 22 '12 at 03:19

4 Answers4

1

You can use reflection, iterate over metadata of your class, and pull fields through the reflection API. Obviously, there is a cost attached to that: using reflection is slower than accessing fields directly; sometimes, considerably. However, you can certainly do it. Here is an example:

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 class exposes many useful properties, such as Name and Type, letting you pick which fields to include in your processing, and which fields to ignore.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • It is very important to use `.GetFields(System.Reflection.BindingFlags.GetField)` or you will get an Exception trying to read a field with no getter. – Erik Philips Apr 22 '12 at 04:31
  • @ErikPhilips Thanks for the important note! As a side note, if you see a 100% certain change like this one, feel free to edit the answer: if an author does not like the change, he or she can always revert your edits. Thanks again! – Sergey Kalinichenko Apr 22 '12 at 10:28
0

Put your 'fields' in a dictionary.

And here's how to iterate a dictionary: What is the best way to iterate over a Dictionary in C#?

Community
  • 1
  • 1
Steve Wellens
  • 20,506
  • 2
  • 28
  • 69
0

For .NET/C#, type introspection is handled via the System.Reflection namespace. This allows you to retrieve information about types, and dynamically invoke methods that are unknown at compile time.

How in terms would you achieve the concatFields method? Is there a way to iterate through the class's fields (without knowing the names of the fields) and call ToString() on each.

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;
}

In example B scenario, how would you apply the same method on all Fields provided they were the same type.

If you know the type at compile time, you can cast to it:

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

Or, you can dynamically invoke via reflection:

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
}
Mark Brackett
  • 84,552
  • 17
  • 108
  • 152
0

This is how I would do this:

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>();
    }
}
ninja
  • 106
  • 4