C# Generic Type Inheritance - c#

I have an interface, ICheese, that I would like to be able to extend as I need. It is contained by class that is implementing the IFruit interface:
public interface IFruit<T> where T : ICheese
{
T : cheese { get; }
}
This was done to dodge the fact that C# doesn't have return type covariance; I want to be able to have any implementation of IFruit and know that it has some version of ICheese inside of it.
IFruit talks to a number of ICrackers, who have a reference to IFruit:
public interface ICracker<T> where T : ICheese
{
void Initialize(IFruit<T> fruit);
}
public abstract class Cracker<T> where T : ICheese
{
IFruit<T> fruit
public void Initialize(IFruit<T> fruit)
{
this.fruit = fruit;
}
}
This works so long as the implementation of ICracker specifically defines which kind of ICheese it is going to use:
public class Apple : IFruit<Cheddar> {/* Implementation of Class */}
public class Saltine : Cracker<Cheddar> {/* Implementation of Class */}
In that instance, calling Initialize(new Apple()) on an instance of Saltine works.
However, if we have an ICracker like this:
public class Ritz : Cracker<ICheese> { /* Implementation of Class */ }
I cannot pass an Apple into Rizt's Initialize() function, even though Cheddar inherits from ICheese. Is there a way where I can get this to work or a pattern that would accomplish the same goals? The basic idea is that I want ICrackers to be able to say "I need at least this version of ICheese" and be able to accept any kind of IFruit that provides at least that version of ICheese.

You can make IFruit covariant in T:
public interface IFruit<out T> where T : ICheese
{
T Cheese { get; }
}

Related

Creating an object with the interface name vs class name in C# [duplicate]

I have seen an Interface instance being generated from a class many times. Why do we use interface this way? An interface instance is created only itself with the help of the derived class and we can access only these interface members through this instance. How does this give an advantage? I'm so confused.
interface IPrint
{
void Print();
}
class Sample : IPrint
{
public void Print()
{
Console.WriteLine("Print...");
}
public void Sample()
{
Console.WriteLine("Sample...");
}
}
class Program
{
static void Main(string[] args)
{
IPrint print = new Sample();
print.Print();
}
}
Interfaces define that a class MUST be able to do something. This means that you know the object being worked on will do what you want to be able to do. It allows you greater freedom and is one of the advantages of OOP. This is a deep topic but a very basic example would be this:
public interface IAnimal
{
string Speak();
}
public class Dog : IAnimal
{
public string Speak()
{
return "Woof, woof";
}
}
public class Cat : IAnimal
{
public string Speak()
{
return "Meow";
}
}
public class Parrot : IAnimal
{
public string Speak()
{
return "Sqwark!";
}
}
Then you could use any animal you like!
class Program
{
static void Main(string[] args)
{
// Writes Woof, Woof
IAnimal animal = new Dog();
Console.WriteLine(animal.Speak());
// Now writes Meow
animal = new Cat();
Console.WriteLine(animal.Speak());
// Now writes Sqwark etc
animal = new Parrot();
Console.WriteLine(animal.Speak());
}
}
This also allows you to then get into things like Inversion Of Control where you would take an item in like this and you could pass a dog, cat or parrot and the method would always work, not knowing or caring which animal it was:
public void ShoutLoud(IAnimal animal)
{
MessageBox.Show("Shout " + animal.Speak());
}
This then makes ShoutLoud unit testable because you could use a mock object rather than a real animal. It basically makes your code flexible and dynamic rather than rigid and tightly coupled.
Also, expanding on Matthew's question. In C# you can only inherit from one base class but you can have multiple interfaces. So, you could have:
public class Dog : IAnimal, IMammal, ICarnivor
This allows you to have small interfaces (recommended) that then allow you to build up so giving maximum control over what an item can / must do.
Using an interface this way gives you the ability to create methods that use standard template of the interface. So here you might have many classes of printer that all inherit from IPrinter
class SamsungPrinter : IPrinter
{
// Stuff and interface members.
}
class SonyPrinter : IPrinter
{
// Stuff and interface members.
}
interface IPrinter
{
void Print();
}
So for each type SamsungPrinter, SonyPrinter, etc. you can pre-process using something like
public static void PreProcessAndPrint(IPrinter printer)
{
// Do pre-processing or something.
printer.Print();
}
You know from inheriting from IPrinter and using that type in the method parameters that you can always safely use the Print method on what ever object is passed.
Of course there are many other uses for using interfaces. One example of their use is in design patterns, in particular the Factory and Strategy patterns. The description of which and examples can be found here.
I hope this helps.
But how does this differ from, for example, using a base class with virtual methods?
You are all in the assumption that one programmer or one program writes the interface and the classes, but this doesn't always have to be this way.
Maybe you have a complete finished program that works with animals and you have this worked out using:
public abstract class Animal { public abstract string Speak(); }
And then some day you download some awesome DLL from nuget that shows pictures for animals. The class library contains a contract - interface - 'IAnimal':
namespace AwesomeAnimalLibrary
{
public interface IAnimal
{
string AnimalName;
}
}
The class library also maybe contains :
namespace AwesomeAnimalLibrary
{
public class AnimalPhotos
{
[Byte] GetPhotos(IAnimal animal);
}
}
What could you do now ? Your bas class Animal can implement the AwesomeAnimalLibrary IAnimal interface and that's it.
Don't assume that other people will use you abstract base classes but work together using interface contracts.
Interface can not have instance because interface implements only signatures of properties or methods. Interface is just a pointer to an instance of some class:
interface IExample
{
// method signature
void MyMethod();
}
public class MyClass : IExample
{
// method implementation
public void MyMethod()
{
ConsoleWriteline("This is my method");
}
}
// interface pointing to instance of class
IExample ie = new MyClass();
ie.MyMethod();

Base interface in c#

I need some sort of way to mark base interfaces and identify if a class implemented the base interface or its derived interface. c# doesn't allow having 'abstract interface'. Is there any way to do this in c#?
public interface IBaseFoo
{
void BaseMethod();
}
public interface IFoo : IBaseFoo
{
void FooMethod();
}
public class Base
{
}
public class A : Base, IFoo
{
}
public class B : Base, IBaseFoo
{
}
Now in the following method I need to check if the typeCls is implemented the IFoo or IBaseFoo without explicitly specifying types. I need sort of a way to mark the base interface and identify it in the method. (ie: if c# allowed having abstract interface, I could have check if IsAbstract property of interfaces of typeClas)
public bool IsBaseFooImplemented<T>(T typeCls) where T : Base
{
// Here I need to check if the typeCls is implemented the IFoo or IBaseFoo
}
Because IFoo : IBaseFoo, every class implementing IFoo also implements IBaseFoo. But not the other way around, so you can simply check whether typeCls is IFoo.
Do note that changing behavior based on implemented interfaces generally is a design smell that bypasses the use for interfaces in the first place.
//somewhere define
static List<IBaseFoo> list = new List<IBaseFoo>();
public class A : Base, IFoo
{
public A()
{
YourClass.list.add(this);
}
}
public class B : Base, IBaseFoo
{
public B()
{
YourClass.list.add(this);
}
}
//then you can check if a class is IFoo or not.
public bool IsBaseFooImplemented<T>(T typeCls) where T : Base
{
foreach(var c in list )
{
if(typeof(c) == typeCls) return true;
}
return false;
}
I have not tested the code but it should work.

C# Derive From Generic Base Class (T : U<T>)

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.

Create an interface with a method that's 'generic', but it's generic type is the implementer of the interface

Is there any way in C# to have a generic type that is always the implementing type in an interface? Something like this:
interface Foo
{
this GetOtherThis();
}
class Bar : Foo
{
Bar GetOtherThis();
}
Is there any way in C# to have a generic type that is always the implementing type in an interface?
No. The answers given so far don't satisfy this, for two reasons:
You can always implement an interface with a different T
interface IFoo<T>
{
T GetOtherThis();
}
public class NotAString : Foo<string>
{
string GetOtherThis() { ... }
}
This can be fixed somewhere with a constraint: interface IFoo<T> where T : IFoo<T> but that still doesn't stop this;
public class Good : IFoo<Good> { ... }
public class Evil : IFoo<Good> { /* Mwahahahaha */ }
Inheritance breaks it anyway:
interface IFoo<T>
{
T GetOtherThis();
}
public class WellBehaved : IFoo<WellBehaved>
{
WellBehaved GetOtherThis() { ... }
}
public class BadlyBehaved : WellBehaved
{
// Ha! Now x.GetOtherThis().GetType() != x.GetType()
}
Basically there's nothing in C# which will enforce this for you. If you trust interface implementations to be sensible, then the generic interface scheme is still useful, but you need to understand its limitations.
Yes, you could write your code using a generic interface:
interface Foo<T>
{
T GetOtherThis();
}
class Bar : Foo<Bar>
{
Bar GetOtherThis();
}
Note: There is no generic constraint you can put on T to make T be the implementing class. Jon Skeet explains it much better detail.

Interface inheritance with an internal base

I was wondering if there's a way to accomplish the following:
In my project, I have defined an interface, let's say IFruit. This interface has a public method GetName(). I also declare an interface IApple which implements IFruit and exposes some other method like GetAppleType() or something. There are more fruits like IBanana, ICherry, whatever.
Now on the outside, I want only to be able to use the actual fruit implementations and not IFruit itself. But I cannot declare the IFruit interface as private or internal, since the inherited interfaces will then say "cannot implement because the base class is less accessible".
I know this is possible with abstract implementations, but that's not an option in this case: I really need to use interfaces. Is there such an option?
Update
I guess my example need some clarification :) I use MEF to load interface implementations. The loaded collections are based upon IApple, IBanana, ICherry, etc. But IFruit itself is useless, I can't use classes based on only that interface. So I was looking for a way to prevent other developers from implementing solely IFruit, thinking that their class will be loaded (which it won't). So basically, it comes down to:
internal interface IFruit
{
public string GetName();
}
public interface IApple : IFruit
{
public decimal GetDiameter();
}
public interface IBanana : IFruit
{
public decimal GetLenght();
}
But that won't compile due to the less accessible base interface.
One way that you can guarantee this doesn't happen unintentionally is to make IFruit internal to your assembly and then use some adaptor to wrap the type appropriately:
public interface IApple { string GetName(); }
public interface IBanana { string GetName(); }
internal interface IFruit { string GetName(); }
class FruitAdaptor: IFruit
{
public FruitAdaptor(string name) { this.name = name; }
private string name;
public string GetName() { return name; }
}
// convenience methods for fruit:
static class IFruitExtensions
{
public static IFruit AsFruit(this IBanana banana)
{
return new FruitAdaptor(banana.GetName());
}
public static IFruit AsFruit(this IApple apple)
{
return new FruitAdaptor(apple.GetName());
}
}
Then:
MethodThatNeedsFruit(banana.AsFruit());
You could also easily extend this to lazily call GetName on the adapted object, if the name could change over time.
Another option could be to have a DEBUG-only check that does load all IFruit implementers, and then throws an exception if one of them doesn't actually implement IBanana/IApple. Since it sounds like these classes are for internal use inside your company, this should stop anyone from accidentally implementing the wrong thing.
It isn't really possible to do what you're trying, but you can put people off using the IFruit interface with an [Obsolete] attribute, with message to say why.
On your IBanana, IApple, ... interfaces, disable the obsolete warning from appearing.
[Obsolete]
public interface IFruit {
...
}
#pragma warning disable 612
public interface IBanana : IFruit {
...
}
#pragma warning restore 612
If you have somewhow in your code (assuming that I correctly understand your state), something like this:
public class WaterMellon : IFruit, IVegetables...
{
}
and you want to be able to consumer of your framework access only to a methods of IFruit, there is no other known method to me then simply cast.
IFruit fruit = new WaterMelon();
fruit. //CAN ACCESS ONLY TO FRUIT IMPLEMNTATION AVAILABLE IN WATERMELON
If this is not what you're asking for, please clarify.

Categories

Resources