Because the fields are not known at compile time, but rather dynamic and user configurable, I'm going to modify your example program slightly to use an array of properties. Then I'd advocate an approach similar to yours but using your own custom class (here, called MyProperty) rather than string. Performance will be at least as good as (and maybe a tad better than) the string approach, but the benefit is that it gives you more flexibility: if you ultimately decide for performance reasons that you need to use an array or List approach, you can easily embed an array index into your MyProperty class. You'd have to change the implementation of GetData but not your calling code.
public static void Test1() {
SomeClass[] SomeClasses; //created somehow
//in real life, this would be determined dynamically
var properties=new[] {SomeClass.FirstField, SomeClass.AnotherField, SomeClass.AndAnother};
foreach(var sc in SomeClasses) {
foreach(var property in properties) {
Console.WriteLine(sc.GetData(property));
}
}
}
public class SomeClass {
public static readonly MyProperty FirstField=new MyProperty();
public static readonly MyProperty AnotherField=new MyProperty();
public static readonly MyProperty AndAnother=new MyProperty();
private readonly Dictionary<MyProperty, string> myData=new Dictionary<MyProperty, string>();
public string GetData(MyProperty property) {
return myData[property];
}
}
//default implementation of Equals and GetHashCode are fine here
public class MyProperty {}
HOWEVER, since your target application is really about collecting a set of dynamic and user configurable property getters, maybe you really want to make some Funcs? Code like the below will be very fast, and it still has the ability you want, namely it allows you to make a little dynamic, user-configurable list of property getters.
public static void Test2() {
SomeClass[] SomeClasses; //created somehow
//in real life, this would be determined dynamically
var getters=new[] {SomeClass.FirstField, SomeClass.AnotherField, SomeClass.AndAnother};
foreach(var sc in SomeClasses) {
foreach(var getter in getters) {
System.Console.WriteLine(getter(sc));
}
}
}
public class SomeClass {
public static readonly Func<SomeClass, string> FirstField=sc => sc.field0;
public static readonly Func<SomeClass, string> AnotherField=sc => sc.field1;
public static readonly Func<SomeClass, string> AndAnother=sc => sc.field2;
private string field0;
private string field1;
private string field2;
}