I have a class A from which B inherits.
A has a property called Data which is a class that contains some data. There is also BData that again inherits from data.
In other words:
class A
{
public Data data;
}
class B : A
{
public new BData data;
}
class Data
{
public string id = "something";
}
class BData : Data
{
public new string id = "something else";
}
Now, I use a method to read the data from any class and do some logic based on the data.
public bool ReadData<T>(T element) where T : A
{
Console.WriteLine($"Element: {element}");
Console.WriteLine($"Element ID: {element.data.id}");
//do some logic
}
I make a test element for A and B and I pass it to the method like so:
A a = new A();
a.data = new Data();
B b = new B();
b.data = new BData();
ReadData<A>(A);
ReadData<B>(b);
The output I get is this:
Element: A
Element ID: something
Element: B
Element ID:
I can not understand why when I pass the second object, it has a null property. I suspect it might have something to do with the different types (need casting from B to A? is it because I’m hiding Data with BData?) but I can not figure it out. Am I missing something?
What causes this to happen and how can I fix it?
>Solution :
This
class B : A
{
public new BData data;
}
doesn’t make the old data field in
class A
{
public Data data;
}
class disappear. It doesn’t replace it, it simply hides it. Then
public bool ReadData<T>(T element) where T : A
treats every object as A. In particular when you initialize B then its public Data data field (of the base A class) is not initialized and hence stays null. Then even though you pass B, it actually tries to access its data field of A class.
The behaviour is easier to understand if you change the B to
class B : A
{
public BData data2;
}
The moral of this story is: new keyword is dangerous, avoid it.