Creating an object of the type a static method is called on in an inheritance chain in C#
I am trying to do something like this in C#
public class ParentClass {
public static ParentClass GetSomething()
{
var thing = new // ?????
return thing;
}
}
public class ChildClass : ParentClass {
}
And then I want to be able to call the static method on the child class like so:
ChildClass bla开发者_如何学Goh = ChildClass.GetSomething();
e.g. When calling the static method on the child class I want to instantiate an instance of the child class. But I just want the static method defined on the parent. Is this at all possible? I'd be happy even with:
ChildClass blah = (ChildClass) ChildClass.GetSomething();
Thanks!
This smells awful, but you could do this:
public class ParentClass {
public static T GetSomething<T>() where T : ParentClass, new() {
return new T();
}
}
Usage:
ParentClass parent = ParentClass.GetSomething<ParentClass>();
ChildClass child = ChildClass.GetSomething<ChildClass>();
This is legit too:
ParentClass parent = ChildClass.GetSomething<ParentClass>();
which contributes to the smelliness of this (yes it just compiles to ParentClass parent = ParentClass.GetSomething<ParentClass>()
but it still smells).
You cannot 'override' static methods. But you can use generics to tell the ParentClass which derived class you actually means. It's somewhat ugly but it works:
class ParentClass<T> where T : ParentClass<T>, new()
{
public static T GetSomething()
{
T thing = new T();
return thing;
}
}
class ChildClass : ParentClass<ChildClass>
{
}
Test:
ChildClass x = ChildClass.GetSomething(); // works
This line:
ChildClass blah = ChildClass.GetSomething();
is compiled to exactly the same IL as this line:
ChildClass blah = ParentClass.GetSomething();
(when ChildClass
doesn't declare its own GetSomething
method).
I would prefer:
ChildClass blah = ParentClass.GetSomething<ChildClass>();
It's like your casting version, but with angle brackets and the type name coming after instead of before the method name :) (Basically Jason's suggestion, now I've seen it!)
However, this is now somewhat independent of ParentClass
- you can define it anywhere that's useful:
public static class FactoryUtil
{
public static T CreateInstance<T>() where T : ParentClass
{
...
}
}
... or you could provide a factory as a dependency where you need it, making things more testable, potentially...
C# doesn't let you override static methods.
There's nothing stopping you, though, from redefining a new static method on ChildClass
that hides the ParentClass
method. Would doing that help?
精彩评论