Generic inherited type restriction in C# - c#

I have an inelegant solution for what I need, but am looking for an elegant solution to replace it.
The following code doesn't compile, but represents what I would like to do:
interface IWebService
{
}
abstract class BaseClient<T>
{
}
class SpecializedClient : BaseClient<IWebService>
{
}
class ClientHelper<T> where T : BaseClient<*>
{
}
Where the T in ClientHelper<T> is any class that extends BaseClient regardless of the templated type passed in.
The inelegant solution I found is:
class ClientHelper<T, U> where T : BaseClient<U> {}
The reason this becomes inelegant is my project ends up with a class similar to:
class MyClass<A, B, C, D, E, F, G> where A : MyBaseClass<B, C, D, E, F, G>
All the way down to the base class that takes a single type. Is this simply the cost of having a complex inheritance tree of generic classes or is there a simpler way to do this while retaining type restrictions on the templated types?

Your "inelegant" solution is the right one if the public interface of BaseClient exposes it's generic type parameter in any way.
So assuming BaseClient is not as you defined it:
abstract class BaseClient<T>
{
//Something about T here
}
Then T is part of the public interface contract of BaseClient, and therefore part of the public interface contract of ClientHelper (again, assuming that BaseClient<U> is exposed via the interface of ClientHelper).
On the other hand, let's assume it actually is as your example puts it:
abstract class BaseClient<T>
{
//Nothing about T here
}
In that case, you can do:
interface IBaseClient
{
//Nothing about T here
}
abstract class BaseClient<T> : IBaseClient
{
// Whatever you like here
}
and ClientHelper becomes:
class ClientHelper<T> where T : IBaseClient
{
}

One option seems to be:
interface IWebService
{
}
interface IClient<out T>
{
}
abstract class BaseClient<T> : IClient<T>
{
}
class SpecializedClient : BaseClient<IWebService>
{
}
class ClientHelper<T> where T : IClient<object>
{
}
However that will only work if you BaseClient only returns T and never accepts it.

Related

Inheritance of nested generics / nested generics in abstract class C#

I have two abstract classes that can be inherited for explicit usage: A_GUI_Info and A_Info_Data. The GUI_Infos are GUI elements that display data. The Info_Datas are data classes, that transfer specific data to the according GUI_Info.
I want to express the dependency that an explicit GUI_Info has one explicit Info_Data through generics and still allow an inheritance. With other words, I want to avoid that a wrong explicit Info_Data is fed to an explicit GUI_Info. For example, I feed HUD_Info_Data to a Wrist_GUI_Element that does not have the means to represent it. > A kind of type-safety for inherited generics
Example:
class HUDInfoData : A_Info_Data
class HUDInfo<HUDInfoData > : A_GUI_Info<A_Info_Data>
// but the generic cant be inherited like that
class HUDInfo : A_GUI_Info<A_Info_Data>
// doesnt define dependency
class HUDInfo : A_GUI_Info<HUDInfoData >
// also not working
Another approach is restrictions by where T : A_GUI_Info<D> where D : A_Info_Data But it did not work like that.
The final requirement, that I cant get to work is: I have an instance of the explicit Info and want to handle it in a function, that could also handle all other inherited Infos with their according Datas.
public HUD_Info<HUD_Info_Data> obj;
public List<A_GUI_Info<A_Info_Data>> infos;
public void SetConnection(string ID, A_GUI_Info<A_Info_Data> p)
{
infos.Add(p);
}
It may end up that you need to use this kind of data structure:
public abstract class A_GUI_Info<G, D>
where G : A_Info_Data<G, D>
where D : A_GUI_Info<G, D>
{
public G Gui { get; set; }
}
public abstract class A_Info_Data<G, D>
where G : A_Info_Data<G, D>
where D : A_GUI_Info<G, D>
{
public D Data { get; set; }
}
It's not overly nice, but it does tie the two derived types to each other.
You would defined them like this:
public class HUDInfoData : A_Info_Data<HUDInfoData, HUDInfo>
{
}
public class HUDInfo : A_GUI_Info<HUDInfoData, HUDInfo>
{
}
Have you tried:
abstract class A_Info_Data { ... }
abstract class A_GUI_Info<T> where T: A_Info_Data { ... }
And now:
class CriticalData: A_Info_Data { ... }
class CriticalGui: A_GUI_Info<CriticalData> { ... }
The type parameter on the base class only exists on the base class. The more derived class has to define a new type parameter and pipe through the type to the base class's type parameter. This gives you a place to pose more generic constraints.
For example:
class HUDInfo<THudInfoData> : A_GUI_Info<THudInfoData> where THudInfoData : A_Info_Data
Now, HUDInfo<> can take any HudInfoData as long as it derives from A_Info_Data (or if it is A_Info_Data). If you wanted to have HUDExtremelySpecificInfo which could only take HUDExtremelySpecificInfoData, that would look like:
class HUDExtremelySpecificInfo<THudInfoData> : A_GUI_Info<THudInfoData>
where THudInfoData : HUDExtremelySpecificInfoData
If you never want to specify the type because you know that it will always be HUDExtremelySpecificInfoData, you can also declare either both:
class HUDExtremelySpecificInfo<THudInfoData> : A_GUI_Info<THudInfoData>
where THudInfoData : HUDExtremelySpecificInfoData { .. }
class HUDExtremelySpecificInfo : HUDExtremelySpecificInfo<HUDExtremelySpecificInfoData> { .. }
(where you implement the non-generic HUDExtremelySpecificInfo in terms of the generic HUDExtremelySpecificInfo<>, and can use the generic one if there's a specific even more extremely specific info data subclass that you want to specify)
or just one:
class HUDExtremelySpecificInfo : A_GUI_Info<HUDExtremelySpecificInfoData> { .. }
Thank you all for giving constructive answers. What I try here is not working like preferred (pbbly not possible at all). This is what I came up with:
// abstract definitions
public abstract class AInfo
{
public abstract void SetData(AInfoData data);
}
public abstract class AInfoData
// explicit definitions
public class WristInfo : AInfo
{
public override void SetData(AInfoData data)
{
Data_Info_Wrist d = (Data_Info_Wrist)data; // cast to use
}
}
public class Data_Info_Wrist : AInfoData
// runtime usage
public AInfo instance; (WristInfo)
public void Setup(AInfo info) { }
For Unity workflow I require the explicit class to be non-generic. So this workaround is possibly the best solution. The drawback: The desired type-safety is not given here.

How to add the same functionality to different base classes without duplicating code? [duplicate]

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.

Non-generic class implementation of generic interface is not inherited

If I have this code:
public interface IThing<T> where T : class
{
// ...
}
public class BaseThing<T> : IThing<T> where T : class
{
// ...
}
public class ThingA : BaseThing<string>
{
// ...
}
public class ThingB : BaseThing<Uri>
{
// ...
}
This code fails:
List<IThing<object>> thingList = new List<IThing<object>>();
thingList.Add(new ThingA());
thingList.Add(new ThingB());
Even though ThingA (indirectly) inherits from (and should be an instance of) IThing<T>. Why? Is ThingA/ThingB not an instance of IThing<T>?
This would require your interface to be covariant. For details, see Covariance and Contravariance in Generics.
In this case, you can make this work by using:
// Add out here
public interface IThing<out T> where T : class
{
}
Note that this does place limitations on the interface and what you can do with it, however, as it requires that the type T in the interface be used only as a method return type within the interface, and not used as a type of formal method parameters.
If this is not viable, another option is to create a non-generic IThing interface, and have IThing<T> implement IThing. You could then use List<IThing> for your collection.

Declaring member function in interface

Firstly I am pretty new to C#. I would like to have an interface declare a member function like in the following piece of code
interface IMyInterface {
void MyAction() {
// do stuff depending on the output of function()
}
void Function();
}
here Function is pure virtual and should be implemented by children of IMyInterface. I could use an abstract class instead of an interface but then I could not inherit from other classes... Say for example that MyAction is recursiverly searching a directory for files and applying Function to any file found to make my example clear.
How to change my design in order to overcome the constraint that interfaces cannot implement classes ?
Edit : In C++ what I would do is using templates as such
template<class A>
static void MyAction(const A& a) {
// do stuff depending on the output of A::Function()
};
class MyClass {
void Function();
};
I was wondering if there were an elegant way to do this using interfaces in C#.
In C# you don't have multiple inheritance. You can circumvent this limitation by using composition.
Define your interface like this (Function needs not to be defined here):
public interface IMyInterface
{
void MyAction();
}
Declare an abstract class with an abstract Function and implementing this interface:
public abstract class MyInterfaceBase : IMyInterface
{
public void MyAction()
{
// Do stuff depending on the output of Function().
Function();
}
protected abstract void Function();
}
From this abstract class you can derive a concrete implementation. This is not yet your "final" class, but it will be used to compose it.
public class ConcreteMyInterface : MyInterfaceBase
{
protected override void Function()
{
Console.WriteLine("hello");
}
}
Now let's come to your "final", composed class. It will derive from SomeBaseClass and implement IMyInterface by integrating the functionality of ConcreteMyInterface:
public class SomeBaseClass
{
}
public class MyComposedClass : SomeBaseClass, IMyInterface
{
private readonly IMyInterface _myInterface = new ConcreteMyInterface();
public void MyAction()
{
_myInterface.MyAction();
}
}
UPDATE
In C# you can declare local classes. This comes even closer to multiple inheritance, as you can derive everything within your composing class.
public class MyComposedClass : SomeBaseClass, IMyInterface
{
private readonly IMyInterface _myInterface = new ConcreteMyInterface();
public void MyAction()
{
_myInterface.MyAction();
}
private class ConcreteMyInterface : MyInterfaceBase
{
protected override void Function()
{
Console.WriteLine("hello");
}
}
}
The only way to directly handle this would be to use an abstract class, as the interface cannot contain "logic" of any form, and is merely a contract.
One alternative, however, would be to make an interface and a static class. You could then place your logic in an extension method using the interface.
public interface IMyInterface {
void Function();
}
public static class MyInterfaceExtensions {
public static void MyAction(this IMyInterface object)
{
// use object.Function() as needed
}
}
The main disadvantages here are more types, which reduces maintainability, and a lack of discoverability.
You can define MyAction as extension method:
public interface IMyInterface
{
void Function();
}
public static class MyInterfaceExtensions
{
public static void MyAction(this IMyInterface obj)
{
obj.Function();
}
}
Example:
public class HelloWorld : IMyInterface
{
public void Function()
{
Console.WriteLine("Hello World");
}
public static void Main(string[] args)
{
new HelloWorld().MyAction();
}
}
Output:
Hello World
Interfaces can't implement any behavior they are just contracts. If you want to implement some logic while defining a contract you could use an abstract class.
For that purpose . you need to define abstract class.
You can provide default implementations or you can leave the implementation to the derived class.
If the derived class want to override some thing they can always do that .
This gives them the flexibility to use base along with changes they want to override.
Declare the function's interface (Signature and return types), in an interface,
Then create an abstract class that is defined to implement that interface, and implement a basic default implementation in the abstract class. Then, create other concrete classes that inherit from the abstract class, but when necessary, override the abstract classes base implementation with different implementation.
This sort of problem might best be overcome by separating the external behaviours; MyAction in this case, from the internal implementation; MyFunction.
The point here is understanding what should be part of the interface/contract between this class and others, and what should be part of the implementation of that contract.
Here, the contract between this object and its consumers is defined;
interface IMyInterface
{
void MyAction();
}
Now, a base class which implements this interface, and also enforces a particular behaviour;
abstract class BaseClass : IMyInterface
{
public void MyAction()
{
// do some commmon action
// call derived implementation to deal with the outcome
}
protected abstract void MyFunction();
}
And finally, a concrete implementation which deals with the results of MyFunction in some specific way;
class ConcreteClass : BaseClass
{
protected override void MyFunction()
{
// concrete implementation here
}
}
An interface is a contract, and cannot contain implementation.
From your statement above:
I could use an abstract class instead of an interface but then I could not inherit from other classes
I believe you are hitting the "why does C# not support multiple inheritance" question.
Here is a CodeProject Article on Simulated Multiple Inheritance for C#. You should be able to follow this pattern to achieve a workaround to the simple inheritance model of C#.
This is a proposed feature for C# 8.0:
interface IA
{
void M() { WriteLine("IA.M"); }
}
class C : IA { } // OK
IA i = new C();
i.M(); // prints "IA.M"`
https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md

Best way to refer to my own type

abstract class A<T> where T:A<T>
{
public event Action<T> Event1;
}
class B : A<B>
{
//has a field called Action<B> Event1;
}
Is there a more elegant way to do this? I want stuff (events, etc) in the base class to be able to use the subclass' type.
The pattern you are using does not actually implement the constraint you want. Suppose you want to model "an animal can only be friendly with something of its own kind":
abstract class Animal<T> where T : Animal<T>
{
public abstract void GetFriendly(T t);
}
class Cat : Animal<Cat>
{
public override void GetFriendly(Cat cat) {}
}
Have we succeeded in implementing the desired constraint? No.
class EvilDog : Animal<Cat>
{
public override void GetFriendly(Cat cat) {}
}
Now an evil dog can be friendly with any Cat, and not friendly with other evil dogs.
The type constraint you want is not possible in the C# type system. Try Haskell if you need this sort of constraint enforced by the type system.
See my article on this subject for more details:
http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
What you have works very well. In fact it's very similar to other .NET interfaces and types where you want the interface implementer to use your type, like:
public class MyClass : IEqualityComparer<MyClass>
{
// From the interface IEqualityComparer
public bool Equals(MyClass other) { ... }
...
}
I don't think you need to specify where T:A.
T will be B when you use class B:A
This is also known as CRTP or Curiously recurring template pattern and is a known idiom.
Since A is abstract, you can add abstract methods to A and invoke them from A and B, which will be forced to implement the method, will be the invoker:
abstract class A<T> where T:A
{
public event Action<T> Event1;
public abstract void Method();
public A(){Method();}
}
class B : A<B>
{
//has a field called Action<B> Event1;
public void Method(){ //stuff }
}
On instantiation of B, the base class constructor will call Method() which is only implemented in B, forcing B's instance to be called.
This allows A to invoke subclass specific methods without requiring A to have specific knowledge of Children. The downside is that ALL children must implement Method or re-abstract it to their own children.
My most recent question was marked as a duplicate of this one. I totally agree on that matter. So I came here to take a look at the answers and to read Eric's post on that (very interesting indeed). You can not enforce this at compile time with the type system but you can do this at runtime. The way I implemented this is:
abstract class FooBase<T>
{
protected FooBase()
{
if (typeof(T) != GetType())
{
throw new InvalidOperationException();
}
}
}
By doing this we can plant the seed of an evil dog, but that dog will be aborted at runtime.

Categories