I have a problem with a C# program that includes the following :
class Program
{
static void Main(string[] args)
{
Child childInstance = Child.ParseFromA(@"path/to/Afile") as Child;
}
}
class Parent{
int property;
public static Parent ParseFromA(string filename)
{
Parent parent = new Parent();
// parse file and set property here...
return parent;
}
}
class Child : Parent
{
public void SomeAdditionalFunction() { }
}
When running this code, childInstance
becomes null
.
I tried below assignment with explicit cast, but ended with an exception :Child childInstance = (Child)Child.ParseFromA(@"path/to/Afile");
Since I want to parse some types of files into Parent
and Child
instance, I want to keep the design that generates instances by static methods.
How should I get a proper childInstance
?
A static method cannot reference instance member variables directly. A static method cannot call an instance method directly.
Static methods can't access instance methods and instance variables directly. They must use reference to object. And static method can't use this keyword as there is no instance for 'this' to refer to.
In C#, one is allowed to create a static class, by using static keyword. A static class can only contain static data members, static methods, and a static constructor.It is not allowed to create objects of the static class. Static classes are sealed, means you cannot inherit a static class from another class.
Instance methods need a class instance and can access the instance through self . Class methods don't need a class instance. They can't access the instance ( self ) but they have access to the class itself via cls . Static methods don't have access to cls or self .
You cannot downcast it. Once an object has been created as a Parent
, it will always be a Parent
. It's like trying to downcast a new object()
to a string
: That just won't work - which character sequence should this string represent?
Thus, your only solution is to create the correct object. The only option I see in your case is to make your static method generic:
public static T ParseFromA<T>(string filename) where T : Parent, new()
{
T t = new T();
// parse file and set property here...
return t;
}
Usage:
Child childInstance = Parent.ParseFromA<Child>(@"path/to/Afile");
The generic constraint T : Parent
ensures that T
is a subtype of Parent
, and new()
ensures that T
has a parameterless constructor.
If you insist on using static methods and do not want to use reflection or generics, then you can also consider using new
keyword:
class Parent
{
public static Parent ParseFromA(string filename)
{
Parent parent = new Parent();
parent.Parse(filename);
return parent;
}
protected virtual void Parse(string fileName)
{
...
}
}
class Child : Parent
{
public new static Child ParseFromA(string filename)
{
Child child = new Child();
child.Parse(filename);
return parent;
}
protected override void Parse(string fileName)
{
base.Parse(fileName);
SomeAdditionalFunction();
}
}
Personally I would just use instance methods.
var child = new Child(...);
child.Parse(...);
An extra line of code is a small price to pay for cleaner code, IMHO. static
keyword does not play well with inheritance, as you can see. You can also always wrap instance method into extension method, if you want a one-liner after all:
public static class ParentEx
{
public static T ParseFile<T>(this T source, string fileName) : where T : Parent
{
source.Parse(fileName);
return source;
}
}
and then
var child = new Child().ParseFile(fileName);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With