Calling specific descendant of interface in an implementation of another interface - c#

I have an interface iClass defined. One method in the interface takes another interface, iObject, as an argument.
In one specific implementation of iClass, I need the method to take a specific implementation of iObject, ObjectImplementation - but C# tells me I need to implement the method as is.
Why is this? isn't ObjectImplementation an instance of iObject? How do I get around this? I tried using an abstract class instead and I get into the same mess.
public interface iClass {
bool SomeMethod(iObject object);
}
public interface iObject {
... // some methods here
}
public ObjectImplementation : iObject {
... // some method implementations here
}
public ClassImplementation : iClass {
public bool SomeMethod(ObjectImplementation object) // <- C# compiler yells at me
{
}
}

The contract clearly states that the method requires an iObject. ObjectImplementation is one class implementing this interface. But there might be others. The contract of iClass states that all those implementations are valid parameters.
If you really need to constrain the parameter to ObjectImplementation consider using a generic interface:
public interface IClass<T> where T : IObject
{
bool SomeMethod(T item);
}
public ClassImplementation : IClass<ObjectImplementation>
{
public bool SomeMethod(ObjectImplementation item)
{
}
}

Leaving the iObject as parameter is a way to go, this should also work:
public interface iClass {
bool SomeMethod(iObject obj);
}
public interface iObject {
}
public class ObjectImplementation : iObject {
}
public class ClassImplementation : iClass {
public bool SomeMethod(iObject obj)
{
return false;
}
}

Related

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.

Return a subclass of abstract return type?

My project is structured the following way:
// Abstract class
public abstract class Job
{
public abstract JobResult Run();
}
public abstract class JobResult { }
// Concrete implementer
public class Job1 : Job
{
public override Job1Result Run() { }
}
public class Job1Result : JobResult { }
Each concrete job inherits from Job and implements the method Run which returns a concrete class of JobResult.
However when I do this I get the compiler error:
Job1.Run()': return type must be JobResult to match overridden member
Job.Run()
Is it really not possible to return an inheriting object of the return type when overriding an abstract method?
This is the whole concept of inheritance. Returning parent classes is considered a feature here. Nothing stops you however from returning a Job1Result in Job1
public JobResult Run()
{
return new Job1Result();
}
Then the caller of Job1.Run() will have to know the correct return type and cast it to access Job1Result methods which are specific to that class
You could make Job generic:
public abstract class Job<TResult> where TResult : JobResult
{
public abstract TResult Run();
}
public class Job1 : Job<Job1Result>
{
public override Job1Result Run()
{
//
}
}
Here is an example, I hope it can help you.
public interface IEvent
{
Type GetEventType();
}
public abstract class AEvent<A>: IEvent where A: struct
{
public Type GetEventType()
{
return typeof (A); // return sub struct type
}
}

C# generics question - generic interface constraint

Let's say I have some basic interface which is generics-driven:
public interface Inteface<T> {
void Foo(T t);
}
Now I have some concrete implementation of this interface which is also generic:
public class InterfaceImpl<T> {
public void Foo(T t) {
// Whatever
}
}
This looks OK, but now let's say I have other class:
public class Ololo {
public void BadFunction<TShouldModelInterface>(TShouldModelInterface shouldModelInterface) {
// Whatever
}
}
And let's say I want to perform a check if TShouldModelInterface actually implements any of the possible Interface<T>.
If the interface wasn't generic, I would simply write something like where TShouldModelInterface : Interface.
But is there any way to solve this problem if the interface is a declared as Interface<T>?
public class Ololo {
public void BadFunction<TShouldModelInterface, T>(TShouldModelInterface shouldModelInterface)
where TShouldModelInterface : Interface<T>
{
// Whatever
}
}

Explicitly implementing an interface with an abstract method

Here is my interface:
public interface MyInterface {
bool Foo();
}
Here is my abstract class:
public abstract class MyAbstractClass : MyInterface {
abstract bool MyInterface.Foo();
}
This is the compiler error:
"The modifier 'abstract' is not valid for this item.
How should I go on about explicitly implementing an abstract with an abstract method?
You can't, basically. Not directly, anyway. You can't override a method which is explicitly implementing an interface, and you have to override an abstract method. The closest you could come would be:
bool MyInterface.Foo() {
return FooImpl();
}
protected abstract bool FooImpl();
That still implements the interface explicitly and forces derived classes to actually provide the implementation. Are those the aspects you're trying to achieve?
You have to use an implicit implementation of the interface member instead of an explicit implementation:
public abstract class MyAbstractClass : MyInterface
{
public abstract bool Foo();
}
In fact there is another option than using an abstract helper method which still keeps the implementation private:
public abstract class MyAbstractClass : MyInterface
{
bool MyInterface.Foo() // must be overridden
{ throw NotImplementedException(); // never called
}
}
public class MyDerivedClass : MyAbstractClass, MyInterface
{
bool MyInterface.Foo() // overrides MyInterface.Foo
{ // Place your implementation here
}
}
This pattern will also work if the interface has many methods and only some of them are redefined in the derived class. And, of course, you can also use this to override private interface implementations in general.
The major disadvantage is that Foo cannot be declared abstract in MyAbstractClass, so the compiler cannot ensure that the method is actually overridden. (It's a pity that abstract classes may not have incomplete interface implementations in C#.)
The advantage is that you save one calli instruction that is likely to cause CPU pipeline stalls. However, the impact is quite small, since the method cannot be inlined anyway because of the interface call. So I would recommend it only for performance critical cases.
I'm not sure why you need to. Why not let the concrete implementation of the abstract class implement the member from the interface? It's the same thing really.
An abstract method has no implementation, so it can't be used to explicitly implement an interface method.
I am able to do this
public interface SampleInterface
{
void member1();
void member2();
void member3();
}
public abstract class Client2 : SampleInterface.SampleInterface
{
public void member1()
{
throw new NotImplementedException();
}
public abstract void member2();
public void member3()
{
throw new NotImplementedException();
}
}
public class Client3 : Client2
{
public Client3()
{
}
public override void member2()
{
throw new NotImplementedException();
}
}
In addition to Jon's explanation: this is a way to bypass the problem instead of solving it directly and will work only in certain circumstances, but maybe someone will benefit from this idea.
If you plan to pass all (or at lest most) interface method calls to the derived class, you can do it in the following way:
public interface MyInterface
{
bool Foo();
}
public abstract class MyAbstractClass
{
public abstract MyInterface AsMyInterface();
}
public class MyDerivedClass : MyInterface
{
public override MyInterface AsMyInterface()
{
return this;
}
public bool Foo()
{
return false;
}
}
...
MyAbstractClass c = new MyDerivedClass();
MyInterface i = c.AsMyInterface();
bool b = i.Foo();
Abstract all the interface methods that are implemented in a abstract class, even if you do not use them.
This particular case requires that you are implementing a hierarchy of 2 or more abstract classes, with a interface.
I was trying to implement a hierarchy in C# as well. I needed a Interface but I wanted a Abstract class, because most of the properties are the same for the interface. To do this I had to create a separate Abstract class, with the implementation, and then my Concrete classes, or in my case another abstract class, would inherit the Interface and the Abstract Class.
I do not think that this first one is a good example for many reasons, but I had to have it because the compiler would not allow FooBar to implement Foo and then have another abstract class to inherit FooBar. So I had a abstract class with a abstract method bar(), and the interface with the bar() method.
public interface Foo {
bool bar();
//other stuffs
}
public abstract class FooBar {
public abstract bool bar();
//Other stuffs
}
public abstract class FooBarAbstraction: FooBar, Foo {
//other stuffs
//Don't supply the interface and abstract here
}
public class FooBarConcrete: FooBarAbstraction {
public override bool bar() {
return true;
}
//other stuffs
}
This was my first attempt, then I got curious and started to think about it. I came across this solution. The better solution.
public interface Foo {
bool bar();
bool buzz();
//other stuffs
}
public abstract class FooBar : Foo{
public abstract bool bar();
public abstract bool buzz();
//Other stuffs
}
public abstract class FooBarAbstraction: FooBar {
//other stuffs
//Don't supply the interface and abstract here
// override everything else
public override bool buzz() {
return false;
}
}
public class FooBarConcrete: FooBarAbstraction {
public override bool bar() {
return true;
}
//other stuffs
}

C#: Generic implementation of method doesn't satisfy interface

In this post I talked about using a generic base class to enable me to create repository classes without duplicating loads of basic plumbing code.
Each Repository is accessed through an interface. In the code below, I will only show one of the methods for the sake of brevity:
Interface:
IQueryable<Suggestion> All { get; }
Generic base class
public IQueryable<T> All
{
get { return _unitOfWork.GetList<T>(); }
}
Concrete class (implements the interface and extends the generic base class)
public IQueryable<Suggestion> All
{
get { return _unitOfWork.GetList<Suggestion>(); }
}
I anticipated that I would be able to simply strip the method out of the concrete class, and the compiler would use the generic base class implementation instead and work out that was intended to satisfy the interface. But no!
When I strip the method out I get the old 'does not implement interface member' error.
If I can't do this, have my efforts to use a generic base class not been pointless? Or is there a way around this?
Can you make the interface itself generic then implement a typed version in your concrete class?
public interface IRepository<T>
{
List<T> All { get; }
}
public class Repository<T>
{
public List<T> All
{
get { return new List<T>(); }
}
}
public class SuggestionRepository : Repository<Suggestion>, IRepository<Suggestion>
{ }
I'd still suggest using the generic interface since it will save you from repeating yourself, but this works too.
public interface ISuggestionRepository
{
List<Suggestion> All { get; }
}
public class Repository<T>
{
public List<T> All
{
get { return new List<T>(); }
}
}
public class SuggestionRepository : Repository<Suggestion>, ISuggestionRepository
{ }
Use the virtual keyword and put your interface on your concrete implementation..
public interface IMyInterface<T>
{
IQueryable<T> All { get; }
}
public abstract class MyBaseClass<T> : IMyInterface<T>
{
public virtual IQueryable<T> All
{
get { return _unitOfWork.GetList<T>(); ; }
}
}
public class MyClass : MyBaseClass<Suggestion>, IMyInterface<Suggestion>
{
}

Categories

Resources