Combined inheritance, implementation and generics issue - c#

In example below I want to create multiple types of Puppies inherited from PuppyBase base class that implements IPuppy generic interface. Bark method impemented in base class, the others - in derived CutePuppy class.
I can't get how can I create another puppy here who wants another feed and barks differently?
public interface IPuppy<TBark, TDesiredFood>
{
void Bark(TBark sound);
Task<TDesiredFood> Sleep();
Task Eat(TDesiredFood food);
}
public abstract class PuppyBase:IPuppy<Yap,Sausage>
{
public void Bark(Yap sound)
{
Console.WriteLine(sound.ToString());
}
public abstract Task<Sausage> Sleep();
public abstract Task Eat(Sausage food);
}
class CutePuppy : PuppyBase
{
public override Task<Sausage> Sleep()
{
// Implementation
// ...
throw new NotImplementedException();
}
public override Task Eat(Sausage food)
{
// Implementation
// ...
throw new NotImplementedException();
}
}

To be able to specify generic types on base class you may make it also generic
public abstract class PuppyBase<TBark, TDesiredFood> : IPuppy<TBark, TDesiredFood>
where TBark : ISound
{
public void Bark(TBark sound)
{
Console.WriteLine(sound.ToString());
}
public abstract Task<TDesiredFood> Sleep();
public abstract Task Eat(TDesiredFood food);
}
public interface ISound
{
string ToString();
}
This way for CutePuppy you should
class CutePuppy : PuppyBase<Yap,Sausage>
for NotSoNicePuppy
class NotSoNicePuppy: PuppyBase<Wow,Human>

Related

Can't convert interface to concrete interface

Why i can't convert implementation of interface which concrete implement generic interface? I need for Cat, Dog etc own interface realisation.
public interface IMarker { }
public class ResultA : IMarker
{
}
public class ResultB : IMarker
{ }
public interface IService<T> where T : IMarker
{
public List<T> DoStuff();
}
public interface ICatService : IService<ResultA>
{ }
public interface IDogService : IService<ResultB>
{ }
public class CatService : ICatService
{
public List<ResultA> DoStuff()
{
return new List<ResultA>();
}
}
public class DogService : IDogService
{
public List<ResultB> DoStuff()
{
return new List<ResultB>();
}
}
public abstract class Animal
{
protected readonly IService<IMarker> _svc;
protected Animal(IService<IMarker> svc)
{
_svc = svc;
}
}
public class Cat : Animal
{
public Cat(ICatService svc) : base(svc)
{
}
}
public class Dog : Animal
{
public Dog(ICatService svc) : base(svc)
{
}
}
CS1503 Argument 2: cannot convert from 'ICatService' to 'IService'
I have DI for services i.e. :
services.AddTransient<ICatService, CatService>();
The reason for such behaviour is that in general case IService<ResultA> is not IService<IMarker> (basically I would argue the same cause for C# classes does not supporting variance which is for a pretty good reason - see more here and here).
In this concrete case everything can be fixed by making the interface covariant and leveraging the covariance of IEnumerable<T>:
public interface IService<out T> where T : IMarker
{
public IEnumerable<T> DoStuff();
}
public class CatService : ICatService
{
public IEnumerable<ResultA> DoStuff() => return new List<ResultA>();
}
public class Cat : Animal
{
public Cat(CatService svc) : base(svc)
{
}
}
But not sure that in your actual code you will be able to.
Or just make the base class generic (if this suits your use case):
public abstract class Animal<T> where T : IMarker
{
protected readonly IService<T> _svc;
protected Animal(IService<T> svc)
{
_svc = svc;
}
}
Original answer
CatService does not implement ICatService, i.e. the fact that ICatService inherits only IService<ResultA> does not mean that they are the same, C# is strongly-typed (mostly :-) language and compiler will consider those two interfaces being different ones (though related). You need either to make CatService to implement ICatService:
public class CatService : ICatService
{
// ...
}
Or register and resolve the IService<ResultA> interface (basically skipping intermediate interface at all):
services.AddTransient<IService<ResultA>, CatService>();
// ...
public Cat(IService<ResultA> svc) : base(svc){}

C# restrict a overriding method to return a specific type

I have an abstract class which should have a method returning an instance of a class which should inherit from a base class as well implement an interface.
public abstract class AbstractClass
{
abstract [DonotKnowTheType] GetClassInstance() //The Return type should be an instance of a class which implements TestClass and ISample
}
public class ChildClass : AbstractClass
{
override [DonotKnowTheType] GetClassInstance()
{
//Need to return instance of SampleClass in this example. This could vary, this should be an instance of a class which implements TestClass and ISample
}
}
public class SampleClass : TestClass,ISample
{
//Implementation
}
Please help to achieve this with a good design. Need to restrict developers who writes the overriding method in ChildClass to return only an instance of a class which implements TestClass and ISample. If not, it has to show a compile time error.
You could make your abstract class generic with a contraint on TestClass and ISample:
public abstract class AbstractClass<T> where T: TestClass, ISample
{
public abstract T GetClassInstance(); //The Return type should be an instance of a class which implements AbstractClass and ISample
}
public class ChildClass : AbstractClass<SampleClass>
{
public override SampleClass GetClassInstance()
{
//Need to return instance of SampleClass in this example. This could vary, this should be an instance of a class which implements AbstractClass and ISample
return new SampleClass();
}
}
Try this:
public abstract class TheEnforcer<T> where T: TestClass, IMyInterface
{
protected abstract T GetClassInstance();
}
public class ThePoorClass : TheEnforcer<DerivedTestClass>
{
protected override DerivedTestClass GetClassInstance()
{
throw new NotImplementedException();
}
}
public class TestClass
{
}
public class DerivedTestClass : TestClass, IMyInterface
{
}
public interface IMyInterface
{
}
After your comment:
namespace First {
public abstract class TheEnforcer<T> where T : IMarkerInterface
{
protected abstract T GetClassInstance();
}
public interface IMarkerInterface
{
} }
namespace Second {
using First;
// All this is in separate name space
public class TestClass: IMarkerInterface
{
}
public class DerivedTestClass : TestClass, IMyInterface
{
}
public interface IMyInterface
{
}
public class ThePoorClass : TheEnforcer<DerivedTestClass>
{
protected override DerivedTestClass GetClassInstance()
{
throw new NotImplementedException();
}
} }

Should I include all the interfaces in the inheritance chain?

If I have two interfaces:
interface IGrandparent
{
void DoSomething();
}
interface IParent : IGrandparent
{
void DoSomethingElse();
}
then there are two implementations:
//only includes last interface from the inheritance chain
public class Child1 : IParent
{
public void DoSomething()
{
throw new NotImplementedException();
}
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
// includes all the interfaces from the inheritance chain
public class Child2 : IGrandparent, IParent
{
public void DoSomething()
{
throw new NotImplementedException();
}
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
Are these two implementations identical? (except the class name)? Some people say there are something to do with "implicit and explicit implementation", would some one explain why? I have seen Child2 style more than the other one.
Implicit interface implementation takes place when there is no conflicting method names from diffirent interfaces, and it is the common case.
Excplicit, on the other hand, is when there are conflicting method names, and at this point you have to specify which interface implements in the method.
public interface IFoo
{
void Do(); // conflicting name 1
}
public interface IBar
{
void Do(); // conflicting name 2
}
public class FooBar : IFoo, IBar
{
void IFoo.Do() // explicit implementation 1
{
}
void IBar.Do() // explicit implementation 1
{
}
}
Notice that excplicitly implemented interface methods cannot be public.
Here you can read more about explicit interface implementation.
Talking about your specific example. You can safely use only IParent. Even if you would like to use excplicit interface implementation, you still can do it without specifically mentioning IGrandparent in class declaration.
interface IGrandparent
{
void DoSomething();
}
interface IParent : IGrandparent
{
void DoSomethingElse();
void DoSomething();
}
public class Child : IParent
{
void IGrandparent.DoSomething()
{
}
public void DoSomethingElse()
{
}
public void DoSomething()
{
}
}
EDIT: As Dennis pointed out, there are several other cases of explicit interface implementation usage, including interface re-implementation. I found very good reasoning for implicit vs explicit interface implementation usages in here (you may also want to check out the whole thread, it's fascinating).
They are identical.
This is not about explicit interface implementation, because one can implement interface explicitly using both Child1 and Child2 styles, e.g.:
public class Child2 : IGrandparent, IParent
{
void IGrandparent.DoSomething()
{
throw new NotImplementedException();
}
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
public class Child1 : IParent
{
void IGrandparent.DoSomething()
{
throw new NotImplementedException();
}
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
Note, that this shouldn't be confused with interface re-implementation within class hierarchy:
public class Child1 : IParent
{
public void DoSomething()
{
Console.WriteLine("Child1.DoSomething");
}
public void DoSomethingElse()
{
Console.WriteLine("Child1.DoSomethingElse");
}
}
public class Child2 : Child1, IGrandparent
{
// Child2 re-implements IGrandparent
// using explicit interface implementation
void IGrandparent.DoSomething()
{
Console.WriteLine("Child2.DoSomething");
}
}
I'd avoid Child2 style. It's just a visual trash. Moreover, if IGrandparent isn't your responsibility, then sometime you will get this:
interface IGrandparent : ICthulhu { ... }
Do you want to update your code this way:
public class Child2 : ICthulhu, IGrandparent, IParent { ... }
?

Can you override one of the abstract methods in a base class with another base class?

I have a base class that has some abstract methods on it and there are 21 classes that are inheriting from this base class. Now for one of those abstract methods I want to implement it with a common implementation for 6 of the 21 classes so I thought about creating another base class that would do this.
I am open to suggestions but my main purpose of creating another base class between the current base class and the 21 classes is to keep from repeating the same code in 6 of the 21 classes if I didn't have to.
Here is a sample of code to illustrate the situation:
public abstract class FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public virtual string OtherMethod()
{
return this.SomeMethod();
}
}
public abstract class AnotherBase : FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public override OtherMethod()
{
//this is the common method used by 6 of the classes
return "special string for the 6 classes";
}
}
public class Foo1 : FooBase
{
public override string Bar()
{
//do something specific for the Foo1 class here
return "Foo1 special string";
}
public override string SomeMethod()
{
//do something specific for the Foo1 class here
return "Foo1 special string";
}
}
public class Another2 : AnotherBase
{
public override string Bar()
{
//do something specific for the Another2 class here
return "Another special string";
}
public override string SomeMethod()
{
//do something specific for the Another2 class here
return "Another2 special string";
}
}
Yes, you can derive an abstract class from another abstract class
public abstract class FooBase
{
//Base class content
}
public abstract class AnotherBase : FooBase
{
//it is "optional" to make the definition of the abstract methods of the Parent class in here
}
When we say it is optional to define the abstract methods of the parent class inside of the child class, it is mandatory that the child class should be abstract.
public abstract class FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public abstract string OtherMethod();
}
public abstract class AnotherBase : FooBase
{
public override string OtherMethod()
{
//common method that you wanted to use for 6 of your classes
return "special string for the 6 classes";
}
}
//child class that inherits FooBase where none of the method is defined
public class Foo1 : FooBase
{
public override string Bar()
{
//definition
}
public override string SomeMethod()
{
//definition
}
public override string OtherMethod()
{
//definition
}
}
//child class that inherits AnotheBase that defines OtherMethod
public class Another2 : AnotherBase
{
public override string Bar()
{
//definition
}
public override string SomeMethod()
{
//definition
}
}
So I'm guessing that there will be 5 more classes like Another2 which inherits from AnotherBase that will have a common definition for OtherMethod
Yes, that is entirely possible and frequently done. There is no rule that says that you can have only one base class at the bottommost level of your class hierarchy; subclasses of that class can just as well be abstract and thereby become (somewhat more specialized) base classes for one group of classes indirectly derived from your general base class.
You should specify what exactly those classes do, but.. given the information you provided:
This is the exact problem that the Strategy pattern aims to solve, as shown in the example given in the Head First Design Patterns book.
You have an abstract Duck class, from which other ducks (e.g., RedheadDuck, MallardDuck) derive. The Duck class has a Quack method, that simply displays the string "quack" on the screen.
Now you are told to add a RubberDuck. This guy doesn't quack! So what do you do? Make Quack abstract and let the subclasses decide how to implement this? No, that'll lead to duplicated code.
Instead, you define an IQuackBehaviour interface with a Quack method. From there, you derive two classes, QuackBehaviour and SqueakBehaviour.
public class SqueakBehaviour: IQuackBehaviour
{
public void Quack(){
Console.WriteLine("squeak");
}
}
public class QuackBehaviour: IQuackBehaviour
{
public void Quack(){
Console.WriteLine("quack");
}
}
Now, you compose your ducks with this behaviour as appropriate:
public class MallardDuck : Duck
{
private IQuackBehaviour quackBehaviour = new QuackBehaviour();
public override void Quack()
{
quackBehaviour.Quack();
}
}
public class RubberDuck : Duck
{
private IQuackBehaviour quackBehaviour = new SqueakBehaviour();
public override void Quack()
{
quackBehaviour.Quack();
}
}
You can even inject an instance of IQuackBehaviour through a property if you want the ducks to change their behaviour at runtime.

Is there a way to hide the methods partially in child classes?

This question seems weird, but i came across this question in one of the interviews recently.
I ve been asked, is there a way in c# to hide the methods partially in a inherited child classes?. Assume the base class A, exposed 4 methods. Class B implements A and it will only have the access to first 2 methods and Class C implements A will only have the access to last 2 methods.
I know we can do this way
public interface IFirstOne
{
void method1();
void method2();
}
public interface ISecondOne
{
void method3();
void method4();
}
class baseClass : IFirstOne, ISecondOne
{
#region IFirstOne Members
public void method1()
{
throw new NotImplementedException();
}
public void method2()
{
throw new NotImplementedException();
}
#endregion
#region ISecondOne Members
public void method3()
{
throw new NotImplementedException();
}
public void method4()
{
throw new NotImplementedException();
}
#endregion
}
class firstChild<T> where T : IFirstOne, new()
{
public void DoTest()
{
T objt = new T();
objt.method1();
objt.method2();
}
}
class secondChild<T> where T : ISecondOne, new()
{
public void DoTest()
{
T objt = new T();
objt.method3();
objt.method4();
}
}
But what they wanted is different. They wanted to hide these classes on inheriting from baseclasses. something like this
class baseClass : IFirstOne, ISecondOne
{
#region IFirstOne Members
baseClass()
{
}
public void method1()
{
throw new NotImplementedException();
}
public void method2()
{
throw new NotImplementedException();
}
#endregion
#region ISecondOne Members
public void method3()
{
throw new NotImplementedException();
}
public void method4()
{
throw new NotImplementedException();
}
#endregion
}
class firstChild : baseClass.IFirstOne //I know this syntax is weird, but something similar in the functionality
{
public void DoTest()
{
method1();
method2();
}
}
class secondChild : baseClass.ISecondOne
{
public void DoTest()
{
method3();
method4();
}
}
is there a way in c# we can achieve something like this...
I did it by having 1 main base class and 2 sub bases.
// Start with Base class of all methods
public class MyBase
{
protected void Method1()
{
}
protected void Method2()
{
}
protected void Method3()
{
}
protected void Method4()
{
}
}
// Create a A base class only exposing the methods that are allowed to the A class
public class MyBaseA : MyBase
{
public new void Method1()
{
base.Method1();
}
public new void Method2()
{
base.Method2();
}
}
// Create a A base class only exposing the methods that are allowed to the B class
public class MyBaseB : MyBase
{
public new void Method3()
{
base.Method3();
}
public new void Method4()
{
base.Method4();
}
}
// Create classes A and B
public class A : MyBaseA {}
public class B : MyBaseB {}
public class MyClass
{
void Test()
{
A a = new A();
// No access to Method 3 or 4
a.Method1();
a.Method2();
B b = new B();
// No Access to 1 or 2
b.Method3();
b.Method4();
}
}
Although you can't do exactly what you want, you could use explicit interface implementation to help, in which the interface members are only exposed if it is explicitly cast to that interface...
Perhaps the interviewer may have been referring to method hiding?
This is where you declare a method with the same signature as on in your base class - but you do not use the override keyword (either because you don't or you can't - as when the method in the base class is non-virtual).
Method hiding, as opposed to overriding, allows you to define a completely different method - one that is only callable through a reference to the derived class. If called through a reference to the base class you will call the original method on the base class.
Don't use inheritance. It makes the public or protected facilities of the base class available directly in the derived class, so it simply isn't want you want.
Instead, make the derived class implement the relevant interface, and (if necessary) forward the methods on to a private instance of the underlying class. That is, use composition (or "aggregation") instead of inheritance to extend the original class.
class firstChild : IFirstOne
{
private baseClass _owned = new baseClass();
public void method1() { _owned.method1(); }
// etc.
}
By the way, class names should start with an upper case letter.
There is 2 solutions to hide methods inherited from a base class:
As mentioned by thecoop, you can explicitely implement the interface declaring the methods you want to hide.
Or you can simply create these methods in the base class (not inherited from any interface) and mark them as private.
Regards.
What about injecting base class as an IFirst?
interface IFirst {
void method1();
void method2();
}
interface ISecond {
void method3();
void method4();
}
abstract class Base : IFirst, ISecond {
public abstract void method1();
public abstract void method2();
public abstract void method3();
public abstract void method4();
}
class FirstChild : IFirst {
private readonly IFirst _first;
public FirstChild(IFirst first) {
_first = first;
}
public void method1() { _first.method1(); }
public void method2() { _first.method2(); }
}
Injection keeps you from violating the Interface Segregation Principle. Pure inheritance means that your FirstChild is depending on an interface that it doesn't use. If you want to retain only the IFirst functionality in Base, but ignore the rest of it, then you cannot purely inherit from Base.

Categories