Reputation: 49
Let's say I have a class A with the property "Details" that return an instance of class B.
public class A
{
public virtual B Details {get; set;}
}
Lets say also, I have a class Aext (A extended) that inherits from A. But I want that Aext.Details return an instance of class Bext (B extended) :
public class Aext : A
{
public override Bext Details {get; set;}
}
This will not compile because the type Bext must match the type inherited from A.
Of course, I can easily solve that by just put B as return of Details for Aext.
public class Aext
{
B Details {get; set;}
}
Assignment will work, but I'll have to check everytime I use an instance of Aext if Details is Bext or B.
Do you see a way of doing something cleaner that this solution ?
Thank you.
Upvotes: 2
Views: 5458
Reputation: 121
If you do not want to introduce interfaces, you can do something like this:
public class B
{ }
public class Bext : B
{ }
public class A
{
public virtual B Details { get; set; }
public A()
{
Details = new B();
}
}
public class Aext : A
{
public override B Details => new Bext();
}
However, I would suggest you go with composition and use dependency injection, like this:
public interface IB
{ }
public class B : IB
{ }
public class Bext : IB
{ }
public class A
{
public virtual IB Details { get; set; }
public A(IB details)
{
Details = details;
}
}
public class TestClass
{
public void TestMethod()
{
IB details = new B();
IB extDetails = new Bext();
A instance1 = new A(details);
A instance2 = new A(extDetails);
}
}
This way, you do not need to extend the inheritance hierarchy by creating Aext class. You can contain that strictly to the properties in question.
Upvotes: 0
Reputation: 46
Maybe you can try generics, something like this:
public class A<T> where T : B
{
public T Details { get; set; }
}
public class Aext : A<Bext>
{
}
public class B
{
}
public class Bext : B
{
}
If you need you can override T Details with Bext Details, it will work fine.
Upvotes: 3
Reputation: 6222
No - but I think therefore it indicates the base class is flawed in its design. You are trying to force Interface behaviours onto an Abstract class/method. The base method does nothing, do what exactly is being inherited ? The base class could have a protected member of type B accessed by each inheritor and exposed via their own strongly typed accessor method. The value would be available to all inheritors, but consumers would need to get/set a strongly typed version of the data.
Upvotes: 0