Using reflection to get static property value, a concatenation of derived and base class
c#, reflection
Solution
You'll find all you're missing is an explicit cast:
`(List<string>)this.MarbleType.GetProperty("Nicknames").GetValue(null, null);`
This worked fine for me when I tested it.
And as discussed in the comments, no you shouldn't be using the new keyword really, you're better off naming the base class static method to something else so there is no ambiguity. You are after all in control of this and not using someone else's code.
Now, should you do it this way?
Well, first surely you want to use generics not defined methods to return types:
abstract class Bag<T> where T:marble {
public void DumpBag()
{
// here you can use
// (IEnumerable<string>)typeof(T).GetProperty("Nicknames").GetValue(null, null);
}
}
class RedBag : Bag<RedMarble> {
}
class BlueBag : Bag<BlueMarble> {
}
Of course the second thing you could do is make this not static, in which case the property will be abstract in `Marble`, and overridden in `RedMarble` and `BlueMarble`, and then just accessed in `DumpBag` directly as `Nicknames` rather than using reflection.
Problem
I'm going to do my best to explain my vision here. This is a very lame made-up example. I've got a few different types of `Bag`s, and they all hold their own special type of `Marble`. Each type of `Marble` has its own set of Nicknames (`string`s). Unfortunately, there are other things besides the Marble in the Bag, so generics won't help me here. ``` // Bags abstract class Bag { protected Type MarbleType { get; } protected List<Marble> _marbles; public void DumpBag() { ... } } class RedBag : Bag { override Type MarbleType { get { return typeof(RedMarble); } } } class BlueBag : Bag { override Type MarbleType { get { return typeof(BlueMarble); } } } // Marbles abstract class Marble { public static IEnumerable<string> Nicknames { get { return new List<string>() { "Marble", "RollyThing" } } } } class RedMarble : Marble { public static IEnumerable<string> Nicknames { get { return new List<string>(Marble.Nicknames) { "Ruby" }; } } } class BlueMarble : Marble { ... } ``` So now we get to the details, the implementation of `DumpBag()`. Consider the following call: ``` Bag b = new RedBag(); b.GetMarbles(); b.DumpBag(); ``` I would like it to print: ``` Bag of Marbles (aka "Marble", "RollyThing", Ruby"): - Marble 1 - Marble 2 ... ``` We see that, in order to print that heading, the `Bag` must be able to have knowledge of the derived type of `Marble`, independent of any actual instances. It gets a concatenation of the `Nicknames` of the `Marble` base class, but also the derived `RedMarble`. `DumpBag` needs to do a kind of 'static virtual call'. I've started implementing `DumpBag` with the following: ``` public void DumpBag() { PropertyInfo pi = this.MarbleType.GetProperty("Nicknames", BindingFlags.Static); IEnumerable<string> nicknames = pi.GetValue(null, null); // No instance StringBuilder sb = new StringBuilder("Bag of Marbles (aka "); foreach (string nn in nicknames) sb.Append("\"" + nn + "\", "); Console.WriteLine(sb.ToString()); ... } ``` My questions: - Is this sane? Hopefully I have (or I can) explain my rationale for why I've gone this route. - I get a warning (of course) that `RedMarble.Nicknames` hides `Marble.Nicknames`. Does it seem valid to go ahead and mark it `new`?