Multiple inheritance from the same interface in C# - c#

Please consider the following program:
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
public void DoFoo() => Console.WriteLine("BAR!");
}
public class Baz: Bar, IFoo
{
void IFoo.DoFoo() => Console.WriteLine("baz!");
}
class Program
{
static void Main()
{
Baz baz = new Baz();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
Bar bar = baz;
bar.DoFoo();
IFoo foobar = bar;
foobar.DoFoo();
}
}
It gives the following output which I personally with my C++ background consider highly unexpected:
BAR!
baz!
BAR!
baz!
Having , IFoo in the declaration of Baz seems to be substantial, because otherwise void IFoo.DoFoo() doesn't compile.
Can someone please explain what is going on here (especially the last line)? And what should be done to prevent such behavior in real life? Should one avoid implementing from the same interface at all or there are some other rules to avoid problems?
UPD:
Looks like the principal problem here is not with "multiple inheritance" (which is not real multiple inheritance actually), but with the way interface methods can be implemented in C#. Namely, one can have two different implementations of the same method in the same class, one of which is explicit, another is implicit. E.g. this program:
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
void IFoo.DoFoo() => Console.WriteLine("Foo!");
public void DoFoo() => Console.WriteLine("BAR!");
}
class Program
{
static void Main()
{
Bar baz = new Bar();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
}
}
prints
BAR!
Foo!
The trick with "multiple inheritance" just allows to introduce the explicit implementation from a derived class.
From my point of view this feature of C# is potentially dangerous, because if one implements a method of an interface, one usually expects the same method will be called no matter if it is invoked from the interface or from the class. And this is really the case if one implements everything only explicitly or only implicitly. But if both ways are used, this assumption is broken. So the moral seems to be:
Don't mix implicit and explicit implementation of the same method if you don't have in mind to employ this strange effect for some purpose.
Use explicit implementation in derived classes with caution.

This is a difference in the explicit implementation (void IFoo.DoFoo()) vs the implicit implementation (public void DoFoo()). The compiler will use the explicit implementation first. If you provide both an explicit and implicit implementation then the difference becomes clear:
https://dotnetfiddle.net/7l9gIs
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
public void DoFoo(){ Console.WriteLine("BAR!"); }
}
public class Baz: Bar, IFoo
{
void IFoo.DoFoo(){ Console.WriteLine("baz explicit!"); }
public new void DoFoo(){ Console.WriteLine("baz implicit!"); }
}
public class Program
{
public static void Main()
{
Baz baz = new Baz();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
Bar bar = baz;
bar.DoFoo();
IFoo foobar = bar;
foobar.DoFoo();
}
}
Output
baz implicit!
baz explicit!
BAR!
baz explicit!

Implicit implementations tend to be more common and more convenient for usage. They are less verbose and any usage of the concrete type will have the implementations of the members exposed. Implicit implementations don't include the name of the interface being implemented before the member name, so the compiler infers this. The members will be exposed as public and will be accessible when the object is cast as the concrete type.
Visit this link for more details https://www.pluralsight.com/guides/distinguish-explicit-and-implicit-interface-implementation-csharp

The confusion is starting when you implement Baz from IFoo. Because Bar is already implements IFoo and Baz is the subclass of Bar. So, you dont need to do that.
In object oriented programming its not a best practice, in fact it is worst practice.
If you want to override DoFoo method, use the following code
public interface IFoo
{
void DoFoo();
}
public class Bar : IFoo
{
public virtual void DoFoo()
{
// do something
}
}
public class Baz : Bar
{
public override void DoFoo()
{
// override what you did in Bar class
}
}
In your code, when you try to baz.DoFoo, in fact you are calling bar.DoFoo.Because you didnt override it. Its the problem.

Related

How to use an extension method to make an interface complete

Given an interface IFoo
interface IFoo {
void Do();
void Stuff();
}
Let assume there are (legacy) classes Foo1, Foo2, Foo3 all implementing IFoo.
Stuff can be done by using some methods of IFoo, or in case of the newer classes, by just using DoStuff(). Actually, one might look at it as if DoStuff() was "forgotten" on IFoo.
There are also newer Classes FooX (FooY, ...) implementing IFoo2, in additional those has a method DoStuff();
interface IFoo2 : IFoo {
void DoStuff();
}
I need to accept IFoo objects, and be able to "Do Stuff" on it.
//Let us assume foos = new IFoo[] {new Foo1(), new Foo2(), new Foo3(), new FooX()};
void MyMethod(IFoo[] foos){
foreach(foo in foos){
//DoStuff is not defined in IFoo
foo.DoStuff();
}
}
So, I thought to just define an extension method DoStuff() on IFoo for the legacy classes
public static DoStuff(this IFoo self){
self.Do();
self.Stuff();
}
Unfortunately, this extension method is always called, even for FooX.
I Could do something like
public static DoSomeStuff(this IFoo self){
if(self is IFoo2) {
(self as IFoo2).DoStuff()
} else {
self.Do();
self.Stuff();
}
}
void MyMethod(IFoo[] foos){
foreach(foo in foos){
foo.DoSomeStuff();
}
}
However, the method MyMethod reside in a legacy project, currently not yet aware of IFoo2. Is it possible to find a solution without using IFoo2?
You shouldn't extend IFoo interface, like that. It's break Interface Segregation principle.
If these object represents exactly the same entity in your code you shouldn't use different interfaces for them.
You might create extension method if you want extend functionality of classes which implements interface IFoo, but don't create second interface which represents the same contract. However if you want to change IFoo contract - refactor legacy objects (add missing implementation).
As long as your variable has the type IFoo, the extension method DoStuff will be called. The usual way of solving this is exactly what you propose in your last paragraph, or ensuring that you use IFoo2 instead of IFoo in places where you want the newer interface method to be called.
You can create an abstract subclass that implements the methods Do and Stuff for the classes that at the current time don't implement it.
public abstract class abstractFoo : IFoo
{
public virtual void Do() {}
public virtual void Stuff(){}
}
If you can then inherit from this abstract class
public class Foo: IFoo
{
// interface implementation required
}
becomes:
public class Foo: abstractFoo
{
// interface implementation NOT required
}
IMHO FooX shouldn't be implementing IFoo to begin with and some reconsideration should be made of your current arquitecture.
That said, and not knowing exactly what limitations you are fighting against, could you send the IFooXs through a wrapper? Something like the following:
public class FooXWrapper<T>: IFoo where T: FooX
{
readonly T foo;
bool doCalled;
public FooWrapper(T foo)
{
this.foo = foo;
}
public void Do()
{
doCalled = true;
}
public void Stuff()
{
if (!doCalled)
throw new InvalidOperationException("Must call Do");
foo.DoStuff();
}
}
Its an ugly hack, but given the circumstances...

Is it possible to call the explicit interface implementation of the base class in c#?

I would like this program to compile, and then print the output below:
public interface IFoo
{
void Bar();
}
public class FooBase : IFoo
{
void IFoo.Bar()
{
Console.WriteLine("Hello from base class.");
}
}
public class Foo : FooBase, IFoo
{
void IFoo.Bar()
{
(base as IFoo).Bar(); // doesn't compile
Console.WriteLine("Foo added some behavior!");
}
}
public static class Program
{
public static void Main(string[] args)
{
var foo = new Foo() as IFoo;
foo.Bar();
}
}
Desired output:
Hello from base class.
Foo added some behavior!
Obviously, the code above doesn't compile, because it's an invalid way to use the base keyword. Is there a way to accomplish this, without changing the implementation in the base class to a non-explicit one?
You can simply have the explicit interface implementation in the base class call a protected method in the class for its implementation. This allows other derived classes to still call that protected method while still explicitly implementing the interface (and also not publicly exposing the interface's method through the type itself, which presumably is the actual goal).

Type inference with interfaces

Just the other day I cam across a bug that actually took me a while to figure out.
Somehow it seemed that the wrong overload was executed when executing through an inherited interface. Take a look at this code.
class Program
{
static void Main(string[] args)
{
IBar bar = new Bar();
bar.Execute("TEST");
}
}
public interface IFoo
{
void Execute(string value);
}
public interface IBar : IFoo
{
void Execute(object value);
}
public class Foo : IFoo
{
public void Execute(string value)
{
Console.WriteLine("Foo.Execute - string");
}
}
public class Bar : IBar
{
public void Execute(string value)
{
Console.WriteLine("Bar.Execute - string");
}
public void Execute(object value)
{
Console.WriteLine("Bar.Execute - object");
}
}
The output from this program is "Bar-Execute - object" that for me seems a little strange since a more specific overload is available through the inherited IFoo interface. Can anyone explain this behavior?
Best regards
Bernhard Richter
I think in this blog you can find explanation: http://csharpindepth.com/Articles/General/Overloading.aspx
When the compiler goes looking for instance method overloads, it
considers the compile-time class of the "target" of the call, and
looks at methods declared there. If it can't find anything suitable,
it then looks at the parent class... then the grandparent class, etc.
This means that if there are two methods at different levels of the
hierarchy, the "deeper" one will be chosen first, even if it isn't a
"better function member" for the call.

Is there any way an interface can cause different behavior?

Say I have the following code:
class Foo: IFoo {
public string fooProp { get; set; }
}
interface IFoo {
string fooProp {get; set; }
}
Is it at all possible for there to be different behavior between:
Foo x = new Foo();
someMethod(x);
and:
IFoo x = new Foo();
someMethod(x);
?
I think it may differ. If somebody's used bad style of programming, i.e.:
public void someMethod(IFoo f)
{
if (f is Foo)
{
Foo f1 = (Foo)f;
//Do smth with unique Foo members
}
//Do anything with IFoo members
}
Yes, there is a difference if someMethod has different overloads for IFoo and Foo.
public void someMethod(Foo f)
{
// Overload 1
}
public void someMethod(IFoo f)
{
// Overload 2
}
Foo x = new Foo();
someMethod(x); // Matches overload 1
IFoo x = new Foo();
someMethod(x); // Matches overload 2
(I'm no expert) but in your first scenario, you would get access to everything in Class Foo. In the second scenario, you would only be able to access the IFoo members. So if Foo has additional methods (that aren't part of the interface), you will be able to access them in your first scenario but not the second.
I believe using the interface name instead of the class name is just another way to encapsulate data and only provide access to the interface members. For instance you could have Foo and Bar which both implements IFoo. You could add both of them to, say, a List.
There would never be any difference.
Remember, an interface is a contract. By deriving Foo from IFoo, you are implementing that contract.
In both cases, because Foo is an IFoo and adheres to the contract, the behaviour will always be the same.
Of course, how Foo implements that contract is anybodies guess. But the contract is adhered too by the signature of the interface.
If you have two interfaces and there is a common method name in each of them then the implementing class can implement the same method differently. The it depends how the method is called - via interface or not and via which interface.
See here for a similar question:
Inheritance from multiple interfaces with the same method name
Different bahavior can be, but inside someMethod.
Say you have
class Foo: IFoo {
public fooProp { get; set; }
}
interface IFoo {
fooProp {get; set; }
myCustomProp {get;set}
}
if you have
public void someMethod(Foo _foo){
_foo.myCustomProp; //CAN DO THIS, AS YOUR TYPE IS _FOO_
}
Which will not be possible to do in case when the parameter of the method is defined like.
public void someMethod(IFoo _foo){
_foo.myCustomProp; //NO SUCH METHOD INFO
}
unless you don't cast. So the difference is that decaring IFoo, to decalre generic access parameter, but get less "potential" in terms of data access, but get a huge potential in abstraction over types in your architecture.
So the difference will be only in regard of architecture and program workflow.
You could have an explicitly implemented interface in Foo.
class Foo: IFoo {
private string _fooprop;
private string _ifooprop;
public string fooProp
{
get {return "IFoo";}
set {_fooprop=value;}
}
string IFoo.fooProp
{
get {return "Foo";}
set {_ifooprop=value;}
}
}
interface IFoo {
string fooProp {get; set; }
}
with this, you will have:
IFoo foo1=new Foo();
Foo foo2=new Foo();
Console.WriteLine(foo1.fooProp); // Foo
Console.WriteLine(foo2.fooProp); // iFoo
It's possible if you explicitly implement IFoo:
public class Foo : IFoo
{
public string Prop
{
get { return "Hello Foo"; }
}
string IFoo.Prop
{
get { return "Hello IFoo"; }
}
}
public static void SomeMethod<T>(T foo) where T : IFoo
{
var prop = typeof(T).GetProperty("Prop");
Console.WriteLine(prop.GetValue(foo));
}

Why am I getting an error in C# when mixing explicit implementation and polymorphism?

I am getting this error:
type Bar does not implement interface IFoo
From this code:
public interface IFoo
{
void DoA();
void DoB();
}
public class Foo:IFoo
{
void IFoo.DoA()
{
}
void IFoo.DoB()
{
}
}
public class Bar:Foo
{
void IFoo.DoA()
{
base.doA();
}
void IFoo.DoB()
{
base.doB();
}
}
I am using C# 2.0.
What am I doing wrong?
public class Bar : Foo, IFoo
{
// Your code
}
I have run into this as well. what is 'worse', depending on how you look at it is you can't define the interface implementations to be virtual to be overridden in descendent classes. I have gotten into the habit of doing this:
public class Foo:IFoo
{
void IFoo.DoA()
{
DoACore();
}
void IFoo.DoB()
{
DoBCore();
}
protected virtual void DoACore()
{
}
protected virtual void DoBCore()
{
}
}
public class Bar:Foo
{ protected override void DoACore()
{
base.DoACore();
}
protected override void DoBCore()
{
base.DoBCore();
}
}
See n8wrl's answer as to how you should be doing this. See below for the reason why.
You can't explicity implement interface members (void IFoo.DoA()) when implicitly implementing the interface. In other words, because Bar only implements IFoo by virtue of extending Foo, you cannot use explicit implementation.
This will work:
public class Bar : Foo
{
public void DoA()
{
...
}
public void DoB()
{
...
}
Or this:
public class Bar : Foo, IFoo
{
void IFoo.DoA()
{
...
}
void IFoo.DoB()
{
...
}
A bigger problem that you'll probably face is that since Foo is not abstract, it must implement DoA and DoB. If you also implement these methods in bar, you will not be doing it polymorphically. You'll be hiding the Foo implementations if the code has a handle to the Bar type.
I would suspect the confusion arises over how interfaces were implemented in C++, as abstract classes and multiple inheritance.
In .NET, and interface is simply a contract that says you will implement those methods.
You're code won't compile for the same reason this code wont compile(it would with C++):
public interface IFoo
{
void DoSomething();
}
public abstract class Foo : IFoo
{
}
Foo is declaring that Foo implements IFoo, it doesn't say anything else about anyone.
If you wanted to force derived classes to implement it you would do:
public interface IFoo
{
void DoSomething();
}
public abstract class Foo : IFoo
{
public abstract void DoSomething();
}
Or if you really wanted the interface methods hidden by explicit implementation, then something like n8wrl posted above.
At first, this is not clear what is the task? If the goals was to fix a problem asap, than 'Bar : Foo, IFoo' is the shortest solution.
If you are just trying to learn 'implicit/explicit' interfaces difference, than check this post.
Also notice, that 'n8wrl' solution is arguable. It is ok only if Foo indeed required to implement IFoo explicitly. If no, than there is a simpler way:
public interface IFoo
{
void DoA();
}
public class Foo : IFoo
{
public virtual void DoA() {}
}
public class Bar : Foo
{
public override void DoA() {}
}
Hope this helps.

Categories

Resources