I am trying to find a way to derive a class from a generic base class. Say:
sealed public class Final : Base<Something>
{
}
public class Base<T> : T
where T : Anything // <-- Generics do not allow this
{
}
In C# this does not seem to be possible.
Is there any other solution to achieve something similar to this?
I found this StackOverflow question, but it doesn't seem to solve the issue, or at least I do not understand how it should.
EDIT:
The result I'd like to get is to be able to do something like that:
Anything[] anything;
//Assign some Instances to anything
foreach(Final final in anything){
//do something with final
}
The result I'd like to get is to be able to do something like that:
Anything[] anything;
//Assign some Instances to anything
foreach(Final final in anything){
//do something with final
}
Your foreach loop suggests this: class Anything : Final { … }.
This obviously turns around the inheritance hierarchy as you planned and named it. (You cannot have cycles in your inheritance relationships).
public class Base<T> : T where T : Anything { …
Let me elaborate on this part for a bit. I'll reduce your example even further to just class Base<T> : T.
This is not possible, for good reason. Imagine this:
class Base<T> : T
{
public override string Frobble()
{
Fiddle();
return "*" + base.Frobble() + "*";
}
}
class A
{
public sealed string Frobble() { … }
}
class B
{
}
class C
{
public virtual string Frobble() { … }
}
abstract class D
{
public abstract void Fiddle();
public virtual string Frobble() { … }
}
class E
{
public void Fiddle() { … }
public virtual string Frobble() { … }
}
You get all kinds of absurd situations if class Base<T> : T were allowed.
Base<A> would be absurd because Frobble cannot be overridden in a derived class.
Base<B> would be absurd because you cannot override a method that
doesn't exist in the base class.
Base<C> doesn't work because there is no Fiddle method to call.
Base<D> would not work because you cannot call an abstract method.
Only Base<E> would work.
How would the compiler ever know how to correctly compile Base<T> and analyse code that depends on it?
The point is that you cannot derive from a class that is not known at compile-time. T is a parameter, i.e. a variable, a placeholder. So class Base<T> : T is basically like saying, "Base<T> inherits from some (unknown) class". Class inheritance is a type relationship that requires both involved types to be known at compile-time. (Actually, that's not a super-precise statement because you can inherit from a generic type such as class SpecialList<T> : List<T>. But at the very least, the derived class has to know what members (methods, properties, etc.) are available in the base class.)
Is this what you want?
sealed public class Final : Base<int>{
}
public class Base<T> {
}
You could only do this if Final would be a generic class as well, like so:
public sealed class Final<T> : Base<T>
Then you can put a type restraint on T as either a class, to allow only reference types as T, or an instance of Base<T>, to allow only types that derive from Base<T>:
public class Base<T> where T : Base<T>
I don't know the context of this question, but I ran into same question with a project where I had to make it possible to extend the base class which is already derived by many others. Like:
abstract class Base {}
class FinalA : Base {}
class FinalB : Base {}
// Now create extended base class and expect final classes to be extended as well:
class BetterBase : Base {}
The solution was to create common ancestor and connect through properties:
abstract class Foundation {}
abstract class Base : Foundation
{
Foundation Final { get; }
}
class FinalA : Foundation {}
class FinalB : Foundation {}
class FinalC : Foundation
{
Foundation Base { get; }
}
// Here's the desired extension:
class BetterBase : Base {}
Now BetterBase has connection to final class and if needed, the final classes could have connection with (Better)Base also, as shown in FinalC class.
Related
I am currently consuming a third party dll and have no option to switch off of it or not use it. I have a class that looks like this:
public abstract class ParentClass<T> : ApiClass<T> where T : ApiClass<T>
{
//...stuff
}
This causes a few problems if I want to make a Dictionary or return the ParentClass type so that I don't need to know which child class it is beforehand. To make it easier to develop around this I would like to do something like this:
//ChildClass should be what is passed to the generic, without directly referencing it
public abstract class ParentClass : ApiClass<InheritedClass>
{
//...stuff
}
public class ChildClass : ParentClass
{
}
//Now I could define a dictionary like
Dictionary<KeyClass, ParentClass> Map;
Defining it like the second example would allow me to create a Dictionary as where the first one I'm not sure I can define a Dictionary when I don't have a value for the Generic? A bit more info about the ApiClass, the definition for the ApiClass looks like this:
public abstract class ApiClass<Wrapper> : OtherApiClass where Wrapper : ApiClass<Wrapper>
{
//...Stuff
}
So in a scenario like this, how would I define my ParentClass without a Generic, but where the type passed to ApiClass is the child class of the ParentClass (the ApiClass explicitly needs the child type)?
Edit: Clarified a bit on the value of InheritedClass
Edit2: I am not looking for alternatives, I am asking for how to. If I pass anything other than the last inherited class (the current ParentClass I defined at the beginning of the question) the Api will crash. If the syntax existed it would look something like
public abstract class ParentClass : ApiClass<typeof(this)>
I imagine that the third-party library you're using defines ApiClass like this:
public abstract class ApiClass<T> where T : ApiClass<T>
That's an example of the Curiously recurring template pattern.
Let's turn this in to a concrete example:
public abstract class ApiClass<T> where T : ApiClass<T>
{
public abstract T GetNewInstance();
}
If I had that code, I could consume it like this:
public class MyApiClass : ApiClass<MyApiClass>
{
public override MyApiClass GetNewInstance()
{
return new MyApiClass();
}
}
This allows MyApiClass to have an method, defined as an abstract method in that parent class, that knows about the current instance. Eric Lippert discusses this here.
It has the downside that it can be abused:
public class MyNefariousApiClass : ApiClass<MyApiClass>
{
public override MyApiClass GetNewInstance()
{
throw new NotImplementedException();
}
}
That's legal, but C# doesn't have a way of enforcing that you use class itself as the generic parameter. If we had class MyNefariousApiClass : ApiClass<this> it would, but we don't.
Now, when you say you have a class public abstract class ParentClass<T> : ApiClass<T> where T : ApiClass<T> that that's your code for consuming the third-party library.
If so, then that's not the normal way to consume this pattern. If you're overriding the class it should look like this:
public abstract class ParentClass<T> : ApiClass<T> where T : ParentClass<T>
We can then take this to it's final point and define the ChildClass like so:
public class ChildClass : ParentClass<ChildClass>
{ }
Now, if you want a dictionary that can hold any such ChildClass then you are stuck as the parent is generic. The only somewhat sensible workaround is to use an interface.
public interface IParent
{ }
public abstract class ParentClass<T> : ApiClass<T>, IParent where T : ParentClass<T>
{ }
Then you can write Dictionary<KeyClass, IParent> dictionary = new ....
Looking for help to put such structure together.
Have base generic class:
public class A<T>
where T: class
{
public T info { get; set; }
}
Works good for one step inheritance like:
class B : A<BInfoClass>{}
But need same for higher hierarchy members like, but without making all classes generics:
class C : B<CInfoClass>{}
Need possibility to have specific "info" type for each B, C, D etc. ("info" classes derive from one base):
I'd like to suggest to add one more level of hierarchy just to make generic class to be pure generic.
You can put all common code to the AContainer also.
public class AContainer<T> where T : class, InfoA {
public T info { get; set; }
}
public class A : AContainer<InfoA> {}
public class BContainer<T>: AContainer<T> {}
public class B : BContainer<InfoB> {}
public class CContainer<T>: BContainer<T> {}
public class C : CContainer<InfoC> {}
A, B and C classes are empty classes for the without making all classes generics condition (to be used in Unity)
AContainer BContainer and CContainer are added to make generic possible here.
However it does not look like a place to use generics
Good Evening to Everyone,
I have 2 abstract classes in C# :
public abstract class A
{
}
public abstract class B
{
}
I want in my third Class to decide on run time through the config file to either extend Class A or Class B.
For Example :
public Class C : B or A
Both of the abstract classes provide one abstract method with the same Signature .
No, you can't change/chose base class at run-time as base class is defined at compile time.
It sounds like implementing common interface in both classes and using just interface everywhere else would be good solution in your case.
interface IListener
{
void Listen();
...
}
class CA : A, IListener{ .... }
class CB : B, IListener { .... }
// to use:
IListner listener = useSSL ? new CA(...) : new CB(...);
If I am understanding correctly from your question and the comments (check what #RB said), the appropriate behavior would be to define:
public interface IC
{
}
public class A : IC
{
}
public class B : IC
{
}
Write your code to consume the Interface, and contrive a way to inject the correct concrete class into the consumer.
I have a generic base class something like:
public abstract class SomeThingBase<T> where T : class
I'd like to have another base class something like this:
public abstract class MangerBase<T> where T : SomeThingBase<T>
How do you accomplish this in C#?
When trying to use ManagerBase like this it doesn't seem to work.
class TestManager : ManagerBase<TestSomething>
In order to do this you have to pass your generic declarations in all the way from the top. This can get very messy, so avoid doing it.
public abstract class SomeThingBase<T> where T : class{ }
public abstract class ManagerBase<T, U>
where T : SomeThingBase<U>
where U : class
{ }
It's definitely possible to define, but impossible to actually implement. Assuming you have the below definition:
public abstract class SomeThingBase<T> where T : class { }
public abstract class MangerBase<T> where T : SomeThingBase<T> { }
However, defining a class that implements ManagerBase<T> and SomethingBase<T> is impossible since multiple inheritance is not supported and T cannot meet both constraints without multiple inheritance the generic type.
I currently have a small object hierarchy that looks like this:
public class BaseClass {
// this class is empty and exists only so the others can extend it and share the
// same base type
}
public class ChildA : BaseClass {
public Subject<AssociatedClassA> Results;
}
public class ChildB : BaseClass {
public Subject<AssociatedClassB> Results;
}
In my design I would like to enforce that every class that extends from BaseClass should contain a Subject<SomeType> called Results. I'm wondering if there is a way that I can move Results into the base class or an interface such that I can supply the generic type for the Subject when constructing the base class. For example, it would be awesome if I could do something like this:
ChildA<AssociatedClassA> instance = new ChildA<AssociatedClassA>();
Or even better since there should really only be one template parameter that matches with ChildA if when I constructed it that could be taken care of for me:
ChildA instance = new ChildA();
// Results is automatically set to Subject<AssociatedClassA>
I'm stuck trying to implement this now as if I try to move Results into the base class the Subject requires a template parameter which I can't necessarily supply. There could potentially be more than 2 derived classes and I don't like the idea that someone extending this system has to know to add Results manually to each child class.
Following the suggestions of the 2 answers below this solves my desire to move Results into the base class, however I've run into another issue in that I was hoping to be able to use BaseClass as a generic parameter to methods such that any of the derived classes could be used. For example:
public void ProcessBaseClass(BaseClass base) {
// base could be ChildA or ChildB here
}
This no longer works since BaseClass now requires a type argument. Is there any way that I can have the best of both worlds here or am I stuck due to my design choices?
If appropriate, you can make the parent generic:
public class BaseClass<T> {
public Subject<T> Results;
}
public class ChildA : BaseClass<AssociatedClassA> {
}
public class ChildB : BaseClass<AssociatedClassB> {
}
You can make the base class itself generic:
public class BaseClass<T> {
public T Results { get; protected set; }
}