I have a class with a method that calls a method on an object which is hidden in the class which inherits it (but the new field is inherited from baseField as well), and I need calls to this method to take place on the new field but when I call childClass.doSomething() I get an exception saying baseField is null.
I think this is because baseField in baseClass is being accessed, which hasn't been instantiated but I'm not really sure
How can I get someMethod to use the ExtendedBaseField when accessed from childClass
public abstract class baseClass{
protected BaseField baseField;
public void someMethod(){
baseField.doSomething()
}
}
And a class that inherits it:
public class childClass : baseClass{
protected new ExtendedBaseField baseField = new ExtendedBaseField();
}
new childClass().someMethod(); //null pointer exception
ExtendedBaseField inherits BaseField
You're using the new keyword which creates a new field, not set the old one. I am against making fields protected, they should be properties. also you should camel case all properties, methods and classes in .NET. Also brackets should go on their own line.
As per your comments you wanted typed access on your new type so you should make your base class generic. I have demonstrated that as well.
public abstract class BaseClass<T>
where T: BaseField
{
protected BaseClass(T baseField)
{
this.BaseField = baseField;
}
protected T BaseField{get; private set;};
public void SomeMethod()
{
BaseField.DoSomething()
}
}
public class ChildClass : BaseClass<ExtendedBaseField>
{
public ChildClass() : base(new ExtendedBaseField())
{
}
}
Others have given the correct technical answer: You're explicitly hiding the field in the base class.
I'll speak to the bad practice here, instead.
In C++, there's the concept of RAII. Resource Allocation Is Initialization. In C#, we don't generally have to think of resource allocation the same way we do in C++, but the pattern of RAII is still a good practice.
All fields declared in a class should be initialized inline
protected BaseField baseField = new BaseField();
...or in the constructor for that class
protected BaseField baseField;
public BaseClass<T>()
{
this.baseField = new BaseField();
}
If that is not possible, then use an abstract property instead of a field, which forces the child class to implement and initialize it.
protected abstract BaseField BaseField { get; }
The child class is hiding baseField:
protected new ExtendedBaseField baseField = new ExtendedBaseField();
This creates a new baseField property, so the child class can no longer see the base class' baseField property. Thus, it's never set. Thus, it's null.
Don't hide the base class' field. If you want the base class to use it, have the child class use it to:
public class childClass : baseClass {
public childClass() {
baseField = new ExtendedBaseField();
}
}
Related
I have an abstract class:
public abstract class ExampleBase : IExampleBase
{
protected ExampleBase()
{
this.SetupData();
}
protected abstract Dictionary<int, Adress> RelevantData { get; set; }
protected abstract void SetupData();
public void ProcessData()
{
// use RelevantData
}
}
And a derived class:
public class Example : ExampleBase
{
public Example()
{
}
protected override void SetupData()
{
this.RelevantData = new Dictionary<int, Adress>
{ 1, new Adress { ... } },
{ 2, new Adress { ... } }
}
}
In the base class, ReSharper tells me
Virtual member call in constructor
I understand that it's dangerous to call the method because of the execution order.. but how can I resolve this issue?
Context: I want to set up data in each derived class which will then be processed in the base class. I wanted to call the SetupData() method in the base class since it's the same in every derived class.
Derived class:
Set up the data
Base class:
Process the data
You don't. You accept the fact this is dangerous, and (try to) prevent this. This is a design flaw!
You could prevent this for example by moving the call to the highest level class, or make every class responsible for it's own, thus removing the unsafe part of the method call. Then you don't need another class (a base class) to take responsibility for its deriving classes.
If that isn't possible. Make very clear using comments or any other method available that the developer should take this problem into account when updating the code.
Call SetupData in the constructor of Example (and every other derived class) not ExampleBase and make Example a sealed class.
The problem is that SetupData could access something that would be initialized by the Example constructor. But the Example constructor is called only after ExampleBase constructor has finished.
Your base class constructor is called first. If your override method in your subclass depends on anything done in its constructor it won't work. Personally I'd look for a different design, maybe passing the abstract class into the derived class rather than using inheritance.
So a couple lines of code in every derived class
If you need to control the process order then you can do this
public abstract class MyBase
{
public void ProcessData()
{
bool processData = true;
}
public MyBase()
{
bool myBase = true;
}
public MyBase(int pass)
{
bool myBase = true;
}
}
public class Example : MyBase
{
public void GetData() {}
public Example()
: base(1)
{
bool example = true;
GetData();
ProcessData();
}
}
Well, originally I had a couple of constants (like MAX_SPEED) with different values in every of the derived classes. The idea was to use those values in some methods of the base class. That's when I realized that I cannot do that with constants, so I created read-only properties.
I need a method to assign those values to private fields at the moment of the instantiation, preferably in the base class. But first I have to assing the original values in derived classes. Since those are properties, I couldn't find a way to initialize them while defining, so the only way to do that is in the derived constructors.
That's where the problem comes: values are initialized after their assigning to private fields in the base class. The solution I get away with is to create a virtual method and to do assigning there.
Is there a way to call a base constructor from derived class so that the code from derived constructor will be invoked first?
class BaseClass
{
public BaseClass()
{
System.Console.WriteLine("This should be shown after");
}
}
class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
System.Console.WriteLine("This should be shown first");
}
}
Of course in the example it would work the other way around. Is there a solution?
No. The base class constructor is always executed before the body of the derived class constructor. However:
Any instance variable initializers in the derived class are executed before the base class constructor
The base class constructor can execute virtual methods which can be overridden in the derived class. This is almost always a bad idea though. (All kinds of normal preconditions are invalid at this point. You can observe readonly variables which haven't been set yet because they'll be set in the constructor body, for example. Ick.)
To demonstrate both of these:
using System;
class BaseClass
{
public BaseClass()
{
VirtualMethod();
Console.WriteLine("BaseClass ctor body");
}
public virtual void VirtualMethod()
{
Console.WriteLine("BaseClass.VirtualMethod");
}
}
class DerivedClass : BaseClass
{
int ignored = ExecuteSomeCode();
public DerivedClass() : base()
{
Console.WriteLine("DerivedClass ctor body");
}
static int ExecuteSomeCode()
{
Console.WriteLine("Method called from initializer");
return 5;
}
public override void VirtualMethod()
{
Console.WriteLine("DerivedClass.VirtualMethod");
}
}
class Test
{
static void Main()
{
new DerivedClass();
}
}
Output:
Method called from initializer
DerivedClass.VirtualMethod
BaseClass ctor body
DerivedClass ctor body
Additionally, if your base class constructor takes a parameter, then you can execute some code in the derived class in order to provide an argument:
DerivedClass() : base(SomeStaticMethod())
All of these are fairly smelly though. What's your specific situation?
No, you can't do that. Base classes are always initialized first. However, you can do something like this:
class BaseClass
{
public BaseClass()
{
this.Initialize();
}
protected virtual void Initialize()
{
System.Console.WriteLine("This should be shown after");
}
}
class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
}
protected override void Initialize()
{
System.Console.WriteLine("This should be shown first");
base.Initialize();
}
}
One more option is to make child class constructor as static , so that it executes first than parent class constructor. but it not preferable it violates the oop design
let's say I have a class defined in an assembly with:
public class BaseClass
{
internal BaseClass()
{
}
}
And in another assembly, I would like to instanciate this class with :
BaseClass c = new BaseClass();
I get the CS0143 error.
Trying another way, I try to create a derived class of the first one :
public class DerivedClass : BaseClass
{
}
but same error.
The BaseClass is not sealed. How can I instantiate this class or a derived one? Of course, I can't modify the BaseClass.
You'll have to use reflection to get the internal constructor and invoke it:
var ci = typeof(BaseClass).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
var instance = (BaseClass)ci.Invoke(new object[0]);
Since the existence of the constructor is only discovered at run-time, this approach will break if the constructor of BaseClass is changed or removed.
1) You want an actual instance of the base class:
There needs to be some method in the assembly that it's in that constructs it for you. This would normally be called a "factory". It might look like this:
public class BaseFactory
{
public static BaseClass Create() { return new BaseClass(); } //may also add other creation logic
}
Note that such a creation method may even be in BaseClass itself, or it could be in another class. (If the constructor was private it would need to be in the class itself.)
2) You want an instance of the derived class. (Perhaps you're not supposed to be able to construct the base class. If this is true it probably should be abstract.)
public class Derived : BaseClass { }
public class Foo
{
public void Bar() { Derived d = new Derived();}
}
It's hard to tell from your question if DerivedClass is in the same assembly as BaseClass. If it is, just instantiate the derived class:
BaseClass c = new DerivedClass();
And, like Branko stated, if you have control of the project in which BaseClass lives, you can use InternalsVisibleTo.
Let's say I have declared the following classes:
class BaseClass{
/* properties, constructors, getters, setters etc. */
public static BaseClass Create(string url){
/*will return, depending on url, a BaseClass or a SubClass object*/
}
public void Method(){
/* some code here */
}
}
class SubClass: BaseClass{
/* other properties, constructors, getters, setters etc. */
new public void Method(){
/* some other code here */
}
}
Now in my Main method I would like to do something along the lines of:
BaseClass baseClass = BaseClass.Create(url);
if(baseClass.GetType()==typeof(SubClass)){
baseClass.Method();
}
The idea here, of course, is to use Method as it is implemented in SubClass. It may be a silly question but how do I do that? I can't cast a base class into a subclass so I'm not sure...
EDIT
Clarified my question. Even though baseClass was declared as a BaseClass instance, baseClass is SubClass will return trueif url is such that Create returns a SubClass instance.
It looks like you might be looking for polymorphism, but I can't be sure from the description. What is the concrete use case for what you're trying to do?
class BaseClass{
public virtual void Method(){
Console.WriteLine("BaseClass");
}
}
class SubClass : BaseClass{
/* other properties, constructors, getters, setters etc. */
public override void Method(){
Console.WriteLine("SubClass");
}
}
static class Test
{
public void go() {
BaseClass instance = new SubClass();
instance.Method(); // prints "SubClass"
}
}
If it doesn't make sense for the base class to have an implementation, then declare the class and the method as abstract -- this forces the derived classes to override the method, guaranteeing that any instantiated class instance will have a valid implementation.
Well I don't know why you would want to do that?
There is no way that the type of an instance of BaseClass will be equal to the type of SubClass.
That could only be possible if you created a instance of SubClass and then cast it to BaseClass. But in that case you could just cast it back to SubClass to call Method()
If you instansiate the baseClass as BaseClass you will not be able to call the method as SubClass, but if you write
BaseClass baseClass = new SubClass();
if (baseClass is SubClass)
{
SubClass subClass = baseClass as SubClass;
subClass.Method();
}
it will call the method as the SubClass is defined.
First of all: you have to initialise your variable as an instance of SubClass, otherwise there is no way.
Then declare the method in the base class virtual,
or
cast the object to SubClass, and call the Method that way.
So either
class BaseClass{
/* properties, constructors, getters, setters etc. */
virtual public void Method(){
/* some code here */
}
}
or
((SubClass)baseClass).Method();
I've got a (poorly written) base class that I want to wrap in a proxy object. The base class resembles the following:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
public BaseClass(int someValue) {}
//...more code, not important here
}
and, my proxy resembles:
public BaseClassProxy : BaseClass
{
public BaseClassProxy(bool fakeOut){}
}
Without the "fakeOut" constructor, the base constructor is expected to be called. However, with it, I expected it to not be called. Either way, I either need a way to not call any base class constructors, or some other way to effectively proxy this (evil) class.
There is a way to create an object without calling any instance constructors.
Before you proceed, be very sure you want to do it this way. 99% of the time this is the wrong solution.
This is how you do it:
FormatterServices.GetUninitializedObject(typeof(MyClass));
Call it in place of the object's constructor. It will create and return you an instance without calling any constructors or field initializers.
When you deserialize an object in WCF, it uses this method to create the object. When this happens, constructors and even field initializers are not run.
If you do not explicitly call any constructor in the base class, the parameterless constructor will be called implicitly. There's no way around it, you cannot instantiate a class without a constructor being called.
At least 1 ctor has to be called. The only way around it I see is containment. Have the class inside or referencing the other class.
I don't believe you can get around calling the constructor. But you could do something like this:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
protected virtual void Setup()
{
}
}
public BaseClassProxy : BaseClass
{
bool _fakeOut;
protected BaseClassProxy(bool fakeOut)
{
_fakeOut = fakeOut;
Setup();
}
public override void Setup()
{
if(_fakeOut)
{
base.Setup();
}
//Your other constructor code
}
}
If what you want is to not call either of the two base class constructors, this cannot be done.
C# class constructors must call base class constructors. If you don't call one explicitly, base( ) is implied. In your example, if you do not specify which base class constructor to call, it is the same as:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base() { }
}
If you prefer to use the other base class constructor, you can use:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base(someIntValue) { }
}
Either way, one of the two will be called, explicitly or implicitly.
When you create a BaseClassProxy object it NEEDS to create a instance of it's base class, so you need to call the base class constructor, what you can doo is choose wich one to call, like:
public BaseClassProxy (bool fakeOut) : base (10) {}
To call the second constructor instead of the first one
I am affraid that not base calling constructor isn't option.
I ended up doing something like this:
public class BaseClassProxy : BaseClass
{
public BaseClass BaseClass { get; private set; }
public virtual int MethodINeedToOverride(){}
public virtual string PropertyINeedToOverride() { get; protected set; }
}
This got me around some of the bad practices of the base class.
constructors are public by nature. do not use a constructor and use another for construction and make it private.so you would create an instance with no paramtersand call that function for constructing your object instance.
All right, here is an ugly solution to the problem of one class inheriting the constructors of another class that I didn't want to allow some of them to work. I was hoping to avoid using this in my class but here it is:
Here is my class constructor:
public MyClass();
{
throw new Exception("Error: Must call constructor with parameters.");
}
OK now you were warned that it was ugly. No complaints please!
I wanted to force at least the minimal parameters from my main constructor without it allowing the inherited base constructor with no parameters.
I also believe that if you create a constructor and do not put the : base() after it that it will not call the base class constructor. And if you create constructors for all of the ones in the base class and provide the same exact parameters for them in the main class, that it will not pass through. But this can be tedious if you have a lot of constructors in the base class!
It is possible to create an object without calling the parameterless constructor (see answer above). But I use code like this to create a base class and an inherited class, in which I can choose whether to execute the base class's init.
public class MyClass_Base
{
public MyClass_Base()
{
/// Don't call the InitClass() when the object is inherited
/// !!! CAUTION: The inherited constructor must call InitClass() itself when init is needed !!!
if (this.GetType().IsSubclassOf(typeof(MyClass_Base)) == false)
{
this.InitClass();
}
}
protected void InitClass()
{
// The init stuff
}
}
public class MyClass : MyClass_Base
{
public MyClass(bool callBaseClassInit)
{
if(callBaseClassInit == true)
base.InitClass();
}
}
Here is my solution to the problem
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(new Child().Test);
}
public class Child : Parent {
public Child() : base(false) {
//No Parent Constructor called
}
}
public class Parent {
public int Test {get;set;}
public Parent()
{
Test = 5;
}
public Parent(bool NoBase){
//Don't do anything
}
}
}
A simple elegant solution. You can change it according to your need.
Another simple solution from me:
class parent
{
public parent()
{
//code for all children
if (this.GetType() == typeof(child1))
{
//code only for objects of class "child1"
}
else
{
//code for objects of other child classes
}
}
}
class child1 : parent
{
public child1()
{}
}
// class child2: parent ... child3 : parent ... e.t.c