derived instance in base class - c#

class baseClass
{
derivedClass nm = new derivedClass();
}
class derivedClass : baseClass
{
}
This code builds fine. What might be the possible reason for C# to allow creating derivedClass objects in baseClass. Can you think of any specific reasons for doing this?

This code builds fine.
Yes - why do you think it wouldn't?
What might be the possible reason for C# to allow creating derivedClass objects in baseClass.
Because there's no reason to prohibit it?
Can you think of any specific reasons for doing this?
Static factory methods, for example?
// BaseClass gets to decide which concrete class to return
public static BaseClass GetInstance()
{
return new DerivedClass();
}
That's actually a pretty common pattern. We use it a lot in Noda Time for example, where CalendarSystem is a public abstract class, but all the concrete derived classes are internal.
Sure, it's crazy to have the exact example you've given - with an instance field initializing itself by creating an instance of a derived class - because it would blow up the stack due to recursion - but that's not a matter of it being a derived class. You'd get the same thing by initializing the same class:
class Bang
{
// Recursively call constructor until the stack overflows.
Bang bang = new Bang();
}

A developer I used to work with produced this code in our codebase. I personally agree its useful.
public class Foo
{
public static Foo MagicalFooValue
{
get { return Bar.Instance; }
}
private class Bar : Foo
{
//Implemented as a private singleton
}
}

One obvious case is to have a factory method in the base class returning appropriate implementations based on some condition.

derivedClass can be instantiated in baseClass because it is an accessible class. There is no reason why c# should restrict you from doing so. Likewise, you can create an instance of baseClass within baseClass itself.

Related

Call (static) method from child clases

I've created an abstract class, lets call it FooBarizable, that is the parent of 2 clases(more in the practice), Foo and Bar. Now, I have a FooBarizableManager that manages Foo and Bar classes, depending on his type. And from this FroobarizableManager, I want to call getFooBarizables(). Let's see the structure:
FooBarizable.cs:
public abstract class FooBarizable{
public string Name { get; set; }
public static IEnumerable<FooBarizable> GetFooBars(){
throw new NotImplementedException();
}
}
Foo.cs:
public class Foo : FooBarizable{
public static IEnumerable<FooBarizable> GetFooBars(){
return API.getFoos();
}
}
Bar.cs:
public class Bar : FooBarizable{
public static IEnumerable<FooBarizable> GetFooBars(){
return API.getBars();
}
}
FooBarizableManager.cs:
public class FooBarizableManager {
private Type type;
public FooBarizableManager(Type _t){
this.type = _t;
}
public void showFooBarizables(){
MethodInfo method = type.GetMethod("GetFooBars");
IEnumerable<FooBarizable> FooBars = (IEnumerable<FooBarizable>)method.invoke(null, null);
show(FooBars);
}
...
}
So, my problem is that I want to get the object collection from the manager, using the type, but enforce child classes to implement getFooBars() method.
Problems I've faced:
.Net does not allow to define static abstract methods, so I cannot create public static abstract IEnumerable<FooBarizable> GetFooBars() and enforce child class to implement it.
The way that is implemented does not enforce the implementation of the method in child classes, but I try to at least throw a NotImplementedException. The problem is that when I call MethodInfo method = type.GetMethod("GetFooBars"); in the manager, if the subclase does not implements the method, method is null, and NullPointerExceptionis called instead.
I've tried to create an instance method instead of static a static one, it solves the enforce problem because child classes have to implement it, But it does not seem correct to me to create an unnecessary instance to call a method.
So, is there any solution to enforce child classes to implement getFooBar() method? if not, how can I throw the NotImplementedException instead of NullPointerException?
is there any solution to enforce child classes to implement getFooBar() method?
Not for static methods. Static methods are tied to the specific class, so they can't be inherited, nor abstract or virtual.
If you want to make the method polymorphic it needs to be an instance method.
how can I throw the NotImplementedException instead of NullPointerException
The result you're getting that exception is because the type does not have a GetFooBars method, so method is null. So you could check for null first:
public void showFooBarizables(){
MethodInfo method = type.GetMethod("GetFooBars");
if(method == null)
throw new NotImplementedException();
IEnumerable<FooBarizable> FooBars = (IEnumerable<FooBarizable>)method.invoke(null, null);
show(FooBars);
}
But throwing that exception is a little misleading because it may seem to the caller that the showFooBarizables method is not implemented, not the underlying GetFooBars.
Since these method seem to be factory methods, perhaps you need a factory for each type instead? It seems like you are trying to use generics as a replacement for overloads. Factory methods generally aren't generic since they have to have different logic for each type. You could create a "base" factory that contains common code, then sub-class the factory for each specific type.
Of course .NET doesn't allow you to write virtual static methods :)
The whole point of virtual methods is that when you call the Base.DoSomething method on an instance of type Derived, it's the code in Derived.DoSomething that executes. But that means you need the instance to know its actual runtime type, so that you know what method is really supposed to be executed.
A typical alternative is to use some form of a factory interface. That is, instead of querying Foo.GetFooBars or Bar.GetFooBars, you'll get an instance of a provider of the relevant instance type, e.g. Fooizer.GetFooBars and Barizer.GetFooBars, where both Fooizer and Barizer implement IFooBarProvider. GetFooBars doesn't fit into the FooBarizable interface - because that's not where it belongs. Object-oriented design, responsibility, substitution principles and all that :)
Then, if you need to enforce the implementation in code (e.g. to make sure someone doesn't forget to implement the proper provider), you could make an abstract instance method or property on your type:
public abstract class FooBarizable
{
protected abstract IFooBarProvider GetDefaultProvider();
}
Depending on what you're actually trying to do, it might make sense to make those classes generic. Or not :)
You cannot force child classes to define a static methods. As you noted, abstract methods cannot be static, and interfaces work with instances only. I think you are trying to put too much into a single class. It looks like your trying to create some franken-factory. Instead just separate the factory functionality and the abstract parent object.
public abstract class FooBarizable {
public string Name { get; set; }
}
Factory example:
public static class FooBarizableFactory {
public static IEnumerable<FooBarizable> GetFooBars(Type type){
var parentType = typeof(FooBarizable);
if (!parentType.IsAssignableFrom(type))
throw new ArgumentException("Not a FooBarizable");
switch(type.Name) {
case "Foo":
return new List<Foo>() { new Foo () };
case "Bar":
return new List<Bar>() { new Bar() };
default:
throw new ArgumentException("Not a known FooBarizable");
}
}
}
Usage:
var fooBars = FooBarizableFactory.GetFooBars(typeof(Foo));
Demo of idea.
.Net does not allow to define static abstract methods
Because C# compiler makes static as abstract and sealed. So you can't make it just abstract or sealed.
The problem is that when I call MethodInfo method =
type.GetMethod("GetFooBars"); in the manager, if the subclase does not
implements the method, method is null, and NullPointerExceptionis
called instead.
I said static is abstract and sealed. So because of it's sealed derived class will not have GetFooBars method.
You can use the BindingFlags.FlattenHierarchy flag. That way it will check also protected and public static classes of base classes. If It's not implemented on derived class it will check base class. So in your stiuation base class GetFooBars will called, if the derived one does not have this method.
There's no way to enforce static methods via any form of inheritance or polymorphism, but a potential workaround would be to implement an extension method(s) for FooBarizable, so that any class that inherits it will have access to the extension.
Static methods are not related to the object (instance) of the class, it is always related to the class itself.
One way to enforce the implementation of a method would be the use of an interface.
Another way, and this is what I think you want, since this method will have different behavior in different instances, would be the use of abstract methods.
public abstract class AbstractClass
{
public abstract int MustIMplementThis(string param1);
}
public class ChildClass : AbstractClass
{
public override int MustIMplementThis(string param1)
{
throw new NotImplementedException();
}
}
All classes that inherits from AbstracClass will have to implement the methods listed on the parent class.

Preventing inheritance of static member

Base:
public abstract class systemClient : IDisposable
{
public static List<systemClient> Collection = new List<systemClient>();
[...]
}
derived class
public class station : systemClient
{
[...]
}
In this setup I can access station.Collection.
Question is:
Is there a way to hide station.Collection ?
You can't. By creating inhClass as a subclass of baseClass inhClass must provide everything that baseClass provides. Otherwise baseClass x = new inhClass() would be invalid.
In this specific case though you have made the method static, that means that it doesn't actually have its own copy of the method. inhClass is just accessing the static one within baseClass.
I agree with Tim B answer. You can't simply "ignore" some methods or properties of a class which you inherits. But, what you can do is implementing an interface, which may do the work you want. For further reading, take a look here.

Base class object as argument for derived class

(Simplified) Scenario:
public class BaseClass
{
public int BaseClassInt {get; set;}
public BaseClass(int pBaseClassInt)
{ this.BaseClassInt = pBaseClassInt; }
}
public class DerivedClass : BaseClass
{
public int DerivedClassInt {get; set;}
public DerivedClass (int pBaseClassInt, int pDerivedClassInt) : base(pBaseClassInt)
{ this.DerivedClassInt = pDerivedClassInt; }
}
If I want to instantiate a DerivedClass-object I have to pass all arguments required to create a BaseClass-object and a DerivedClass-object. Also for every BaseClass-constructor I have to (at least should in my concrete case) provide a constructor with the same arguments in the derived class, plus arguments for the derived class properties. Then, if I change or delete a constructor in the base class I have to change or delete the corresponding contructor in the derived class(es).
I wonder if it is possible to use a constructor for the derived class which accepts a base class-object as an argument:
public DerivedClass(BaseClass pBaseClassObejct, int pDerivedClassInt)
{
// to make clear what I intend to do - looks silly of course
this = (DerivedClass)pBaseClassObject;
this.DerivedClassInt = pDerivedClassInt;
}
This could be called:
DerivedClass DerivedClassObject = new DerivedClass((new BaseClass(1),2);
If constructors in the base class would change, I wouldn´t have to mind it for the derived class. Is there any way to achieve this?
Think about this line for a moment:
this = (DerivedClass) pBaseClassObject;
Let's ignore the fact that you cant set this directly that way, and focus on the rest.
Imagine Giraffe and Elephant are both implementations of AfricanAnimal:
// By extension, ellie is also an AfricanAnimal
Elephant ellie = new Elephant();
// assume ellie is passed in as a param here (she can
// be, because she is an AfricanAnimal after all!):
public Giraffe(AfricanAnimal ellie)
{
this = (Giraffe) ellie; // Can't do this!
}
You can't (and would not want to) force ellie into being a giraffe, because a giraffe may have properties etc. that ellie lacks, and ellie may have properties that Giraffes don't have. Yet, using an AfricanAnimal as your parameter type there, would allow for just that.
Note: You could write that code and pass a Giraffe in, and all would be fine, but then again, that makes little sense; then you might as well use the Giraffe type as the parameter.
If you replace this with an instance variable, you would be able to compile with something like the following...
public Giraffe(AfricanAnimal ellie)
{
this.varOfTypeGiraffe = (Giraffe) ellie;
}
... but as soon as you run it with an Elephant as a a prameter, you will get an exception similar to:
InvalidCastException: Unable to cast object of type 'Elephant' to type 'Giraffe'.
TL;DR: This is a bad idea. Don't even try.
You cannot make a base constructor run from inside the body of any derived method (including the derived constructor). Even if you could, a base instance would not have retained any information about which constructor was used to instantiate it so there would be no way to know which base constructor should be called.
The above refers to the general case where a base constructor can potentially modify application state not directly related to the base class (e.g. by changing the value of static fields somewhere). You could use reflection to copy property values from a base instance to the derived instance being created, but this is practically unworkable because
It requires that you create a base instance in the first place -- what if the base is abstract, or if creating one has side effects?
You need a guarantee that the base constructor does not modify application state. But the aim here is to be independent of what the base constructors do, so you are back to square one.
No, that is not possible and should not be, because it doesn't make sense.
If it was possible and you deleted/changed the base class constructor, you would still need to change the code which creates the base class object that you would use as an argument to the derived class constructor.
Also, not all base classes are concrete. You would not be able to create an abstract base class, right?
This feature is not available. I think what you want is a little like this:
Suppose C# had a keyword allbaseargs and allowed code like this:
public class DerivedClass : BaseClass
{
public int DerivedClassInt { get; set; }
public DerivedClass (allbaseargs, int pDerivedClassInt)
: base(allbaseargs)
{
DerivedClassInt = pDerivedClassInt;
}
}
Then this could only work if BaseClass had only one (accessible) instance constructor.
The compiler should then examine the sole base constructor and substitute the magical word allbaseargs with the parameters of that constructor.
However, C# does not have this feature, and you would have to hand-code everything, which includes changeing all : base(...) calls of all derived classes when the constructor signature changes.
It is allowed to have the signature:
public DerivedClass(BaseClass pBaseClassObejct, int DerivedClassInt)
like you suggest, but you would not be able to chain the : base(...) easily. You would have to equip BaseClass with a construtor that took another instance in and copied all "state" (all instance properties and fields and such) from that other instance to "this". I do not recommend that solution.
This might be help!
Solution A: Create Inherit instead of base!
public static class Test
{
public static T Foo<T>(string text, int num) where T : BaseClass
{
T #base = (T)Activator.CreateInstance(typeof(T), new object[] { text, num });
//...
return #base;
}
public static void Main()
{
InheritClass inherit = Foo<InheritClass>("Hi there", 10);
}
}
Solution B: Copy base to inherit
public static class Test
{
public static TInherit As<TBase, TInherit>(this TBase #this) where TInherit : TBase
{
var type = typeof(TInherit);
var instance = Activator.CreateInstance(type);
foreach (var property in type.GetProperties())
if (property.CanWrite)
property.SetValue(instance, property.GetValue(#this, null), null);
return (TInherit)instance;
}
public static BaseClass Foo(string text, int num)
{
BaseClass #base = new BaseClass(text, num);
//...
return #base;
}
public static void Main()
{
InheritClass inherit = Foo("Hi there", 10).As<BaseClass, InheritClass>();
}
}
Notes: you can have simple 'As()' found here, but i prefer mine (where Inherit : TBase), where it's more safe and support converting base to inherit of inherit class.

Deriving static members

I have a base class that has a private static member:
class Base
{
private static Base m_instance = new Base();
public static Base Instance
{
get { return m_instance; }
}
}
And I want to derive multiple classes from this:
class DerivedA : Base {}
class DerivedB : Base {}
class DerivedC : Base {}
However, at this point calling DerivedA::Instance will return the same exact object as will DerivedB::Instance and DerivedC::Instance. I can solve this by declaring the instance in the derived class, but then every single derived class will need to do that and that just seems like it should be unneccessary. So is there any way to put all this in the base class? Could a design pattern be applied?
There's one really icky way of doing this:
class Base
{
// Put common stuff in here...
}
class Base<T> : Base where T : Base<T>, new()
{
private static T m_instance = new T();
public static T Instance { get { return m_instance; } }
}
class DerivedA : Base<DerivedA> {}
class DerivedB : Base<DerivedB> {}
class DerivedC : Base<DerivedC> {}
This works because there's one static variable per constructed type - e.g. List<string> is a different type to List<int> and so would have separate static variables.
I've taken the opportunity of making it an instance of the derived class as well - I don't know whether that's what you want or not, but I thought I'd at least make it available for you :)
In general though, this is a nasty thing to do. Static variables aren't really designed for this kind of use - I've just abused a feature of generics to get "sort of" the behaviour you asked for.
Also note that Base<DerivedA>.Instance will return the same result as DerivedA.Instance - the property/variable don't "know" that you're using DerivedA.Instance. I don't know whether or not that's important to you.
With the extra non-generic class, you can write:
Base t = DerivedA.Instance;
t = DerivedB.Instance;
If you don't need that, take it out :)
Static methods does not support polymorphism, therefore, such a thing is not possible.
Fundamentally, the Instance property has no idea how you're using it. And a single implementation of it will exist, as it's static. If you really wanted to do this, this "not recommended" solution is available (I got the idea from Jon's solution):
private static Dictionary<Type, Base> instances = new Dictionary<Type, Base>();
public static T GetInstance<T>() where T : Base, new() {
Type ty = typeof(T);
T x;
if (instances.TryGetValue(ty, out x)) return x;
x = new T();
instances[ty] = x;
return x;
}
Short answer: not that I'm aware of. Static members are always nonvirtual and do not readily support polymorphism.
However, you should also ask yourself why you are doing this. Normally, static members are shared resources that every instance of that class (including the derived classes) will find useful. However, when you make a static instance, you are usually building towards a singleton pattern. In this case, you usually want to seal the class so you can't have derived classes, thus rendering the entire point moot. Thus, you should really be analyzing why you are wanting to do this and solve that problem instead.

C#: Determine derived object type from a base class static method

In a C# program, I have an abstract base class with a static "Create" method. The Create method is used to create an instance of the class and store it locally for later use. Since the base class is abstract, implementation objects will always derive from it.
I want to be able to derive an object from the base class, call the static Create method (implemented once in the base class) through the derived class, and create an instance of the derived object.
Are there any facilities within the C# language that will allow me to pull this off. My current fallback position is to pass an instance of the derived class as one of the arguments to the Create function, i.e.:
objDerived.Create(new objDerived(), "Arg1", "Arg2");
Try using generics:
public static BaseClass Create<T>() where T : BaseClass, new()
{
T newVar = new T();
// Do something with newVar
return T;
}
Sample use:
DerivedClass d = BaseClass.Create<DerivedClass>();
Summary
There are two main options. The nicer and newer one is to use generics, the other is to use reflection. I'm providing both in case you need to develop a solution that works prior to .NET 2.0.
Generics
abstract class BaseClass
{
public static BaseClass Create<T>() where T : BaseClass, new()
{
return new T();
}
}
Where the usage would be:
DerivedClass derivedInstance = BaseClass.Create<DerivedClass>();
Reflection
abstract class BaseClass
{
public static BaseClass Create(Type derivedType)
{
// Cast will throw at runtime if the created class
// doesn't derive from BaseClass.
return (BaseClass)Activator.CreateInstance(derivedType);
}
}
Where the usage would be (split over two lines for readability):
DerivedClass derivedClass
= (DerivedClass)BaseClass.Create(typeof(DerivedClass));
You want to create a new instance of derived from inside another instance of derived, using a static factory method on the abstract base class? if so, I wonder Why... But ...
public abstract class MyBase
{
public static T GetNewDerived<T>() where T : MyBase, new()
{
return new T();
}
}
public class DerivedA : MyBase
{
public static DerivedA GetNewDerived()
{
return GetNewDerived<DerivedA>();
}
}
public class DerivedB : MyBase
{
public static DerivedB GetNewDerived()
{
return GetNewDerived<DerivedB>();
}
}
Is this what you want ?
Sounds like you need to make the Create() method abstract. And once you do that you might as well rename it and make it the constructor as well. Then you can have a different Init() method that you call after the object is constructed if you need to, and normal polymorphism effects will handle things.
You can't do it without outside information; either the type of the derived class, an instance of it, or the fully-qualified name of the derived class. Any of these are equivalent to what you're already doing; there isn't a better solution I'm aware of. The very nature of static methods precludes anything more elegant.
I'm not sure what your design goals are but from what you asked it sounds like it might end up with alot of code smell. I think you should really look into the Inversion of Control(IoC) / Dependency Injection (DI) design patterns that are implemented in numerous frameworks such as Microsoft Unity, Castle Windsor, StructureMap, Ninject, Spring.Net and so forth.
I think if you look at using an IoC container it will solve your problem in a much cleaner and loosely coupled way.

Categories

Resources