interface IBase
{
string Name { get; }
}
class Base : IBase
{
public Base() => this.Name = "Base";
public string Name { get; }
}
class Derived : Base//, IBase
{
public Derived() => this.Name = "Derived";
public new string Name { get; }
}
class Program
{
static void Main(string[] args)
{
IBase o = new Derived();
Console.WriteLine(o.Name);
}
}
In this case output will be "Base".
If I explicitly state that Derived implements IBase (which is in fact already implemented by base class Base and such annotation seem to be useless) the output will be "Derived"
class Derived : Base, IBase
{
public Derived() => this.Name = "Derived";
public new string Name { get; }
}
What's the reason for such behavior?
VS 15.3.5, C# 7
It's explained in sections 13.4.4 to 13.4.6 of the C# 5 specification. The relevant sections are quoted below, but basically if you explicitly state that a class implements an interface, that triggers interface mapping again, so the compiler takes that class as the one to use to work out which implementation each interface member is mapped to.
13.4.4 Interface mapping
A class or struct must provide implementations of all members of the interfaces that are listed in the base class list of the class or struct. The process of locating implementations of interface members in an implementing class or struct is known as interface mapping.
Interface mapping for a class or struct C locates an implementation for each member of each interface specified in the base class list of C. The implementation of a particular interface member I.M, where I is the interface in which the member M is declared, is determined by examining each class or struct S, starting with C and repeating for each successive base class of C, until a match is located:
If S contains a declaration of an explicit interface member implementation that matches I and M, then this member is the implementation of I.M.
Otherwise, if S contains a declaration of a non-static public member that matches M, then this member is the implementation of I.M. If more than one member matches, it is unspecified which member is the implementation of I.M. This situation can only occur if S is a constructed type where the two members as declared in the generic type have different signatures, but the type arguments make their signatures identical.
...
13.4.5 Interface implementation inheritance
A class inherits all interface implementations provided by its base classes.
Without explicitly re-implementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes. For example, in the declarations
interface IControl
{
void Paint();
}
class Control: IControl
{
public void Paint() {...}
}
class TextBox: Control
{
new public void Paint() {...}
}
the Paint method in TextBox hides the Paint method in Control, but it does not alter the mapping of Control.Paint onto IControl.Paint, and calls to Paint through class instances and interface instances will have the following effects
Control c = new Control();
TextBox t = new TextBox();
IControl ic = c;
IControl it = t;
c.Paint(); // invokes Control.Paint();
t.Paint(); // invokes TextBox.Paint();
ic.Paint(); // invokes Control.Paint();
it.Paint(); // invokes Control.Paint();
...
13.4.6 Interface reimplementation
A class that inherits an interface implementation is permitted to re-implement the interface by including it in the base class list.
A re-implementation of an interface follows exactly the same interface mapping rules as an initial implementation of an interface. Thus, the inherited interface mapping has no effect whatsoever on the interface mapping established for the re-implementation of the interface. For example, in the declarations
interface IControl
{
void Paint();
}
class Control: IControl
{
void IControl.Paint() {...}
}
class MyControl: Control, IControl
{
public void Paint() {}
}
the fact that Control maps IControl.Paint onto Control.IControl.Paint doesn’t affect the re-implementation in MyControl, which maps IControl.Paint onto MyControl.Paint.
If Derived does not implement IBase and declares new string Name, that means that Derived.Name and IBase.Name are logically not the same. So when you access IBase.Name, it looks for it in Base class, implementing IBase. If you remove new string Name property, the output will be Derived, because now Derived.Name = Base.Name = IBase.Name. If you implement IBase excplicitly, the output will be Derived, because now Derived.Name = IBase.Name. If you cast o to Derived, the output will be Derived, because now you are accessing Derived.Name instead of IBase.Name.
Related
In the following sample class "SomeClass" does not implement "ISomeInterface". Why can't I implement this by passing a more derived interface which does implement the base requirement. Whatever instance would be passed it would still implement the base, am I missing something?
namespace Test
{
public interface IBaseInterface
{
void DoBaseStuff();
}
public interface IChildInterface : IBaseInterface
{
void DoChildStuff();
}
public interface ISomeInterface
{
void DoSomething(IBaseInterface baseInterface);
}
public class SomeClass : ISomeInterface
{
public void DoSomething(IChildInterface baseInterface)
{
}
}
}
This restriction exists because the ISomeInterface expects that any IBaseInterface will satisfy the contract. That is, if you have the following:
public interface IBase {}
public interface IChildA : IBase {}
public interface IChildB : IBase {}
And an interface that expects IBase:
public interface IFoo { void Bar(IBase val); }
Then restricting this in a derived class as you would like:
public class Foo : IFoo { public void Bar(IChildA val) {} }
Would create the following problem:
IChildB something = new ChildB();
IFoo something = new Foo();
something.Bar(something); // This is an invalid call
As such, you're not implementing the contract you said you would.
In this situation, you have two simple options:
Adjust IFoo to be generic, and accept a T that is a derivation of IBase:
public interface IFoo<T> where T : IBase { void Bar(T val); }
public class Foo : IFoo<IChildA> { public void Bar(IChildA val) {} }
Of course, this means that Foo can no longer accept any IBase (including IChildB).
Adjust Foo to implement IFoo, with an additional utility method for void Bar(IChildA val):
public class Foo : IFoo
{
public void Bar(IBase val) {}
public void Bar(IChildA val) {}
}
This has an interesting side-effect: whenever you call ((IFoo)foo).Bar it will expect IBase, and when you call foo.Bar it will expect IChildA or IBase. This means it satisfies the contract, while also having your derived-interface-specific method. If you want to "hide" the Bar(IBase) method more, you could implement IFoo explicitly:
void IFoo.Bar(IBase val) { }
This creates even more inconsistent behavior in your code, as now ((IFoo)foo).Bar is completely different from foo.Bar, but I leave the decision up to you.
This means, with the second version in this section, that foo.Bar(new ChildB()); is now invalid, as IChildB is not an IChildA.
Why can't I implement this by passing a more derived interface which does implement the base requirement. Whatever instance would be passed it would still implement the base, am I missing something?
This is not allowed because of the reasoning I mentioned above, IFoo.Bar expects any IBase, whereas you want to further constrain the type to IChildA, which is not a super-interface of IBase, and even if it were it would not be allowed because it violates the interface implementation, though you could more easily define a second method at that point that does what you want.
Keep in mind that when you implement an interface, you subscribe to a contract, and C# will not let you violate that contract.
This violates the Liskov substitution principle.
ISomeInterface guarantees that the method can be called with any IBaseInterface instance. Your implementation cannot limit that to only accept IChildInterface interfaces.
From MSDN:
When a class or struct implements an interface, the class or struct must provide an implementation for all of the members that the interface defines
This method in the derived
void DoSomething(IChildInterface baseInterface)
Does not have the same signature as the one in the interface:
void DoSomething(IBaseInterface baseInterface)
IChildInterface and IBaseInterface are not the same types. Therefore your derived class does not implement all methods of the interface and you get the compilation error.
For a possible the logic behind having this as a restriction instead of the compiler understanding the inheritance see Liskov's substitution principle as in SLakes answer
You should change some interface to use some type which implements IBaseInterface,
then change the method signatures to use whichever child your SomeClass wants.
public interface ISomeInterface<TSomeChild> where TSomeChild : IBaseInterface
{
void DoSomething(TSomeChild baseInterface);
}
public class SomeClass : ISomeInterface<IChildInterface>
{
public void DoSomething(IChildInterface baseInterface)
{
}
}
If you could do that, then you could do this:
IAnimal cat = new Cat();
IAnimalTrainer dogTrainer = new DogTrainer();
dogTrainer.Train(cat);
An IAnimalTrainer can train any IAnimal. But a DogTrainer can only train Dogs. Thus it's illegal for DogTrainer to implement the IAnimalTrainer interface.
I was wondering if there are any (runtime) difference if I implement an interface on a derived class if the base abstract class implements it already abstract:
public interface IFoo
{
void Bar();
}
public abstract class Base : IFoo
{
public abstract void Bar();
}
public class Derived : Base, IFoo // does this make any difference?
{
public override void Bar()
{
// do something
}
}
Is there any difference writing the "implemention" IFoo on Derived for example when I check if an instance implements an interface at runtime etc.?
Consider following on your example. Must the following be possible?
void f(Base b){
IFoo ifoo = b;
}
Because an object b is a Base, it must be an IFoo because Base implements IFoo. Now consider the following.
var d = new Derived();
f(d);
Since d is a Derived, it is a Base, because derived inherits from Base. Because of this, we can pass it to f, where it is then assigned to an IFoo, as we did before.
Essentially, because a derived class still is also all of its base classes, it already implements all of its base classes' interfaces. The designers of the language acknowledged this and there is no need to redeclare that a derived class is implementing interfaces that are implemented by its base classes.
I guess that maybe your question arises because of where you actually put the method body, but that really isn't relevant. The declaration of the interface is a contract for other consumers of objects of that type. Those consumers don't care where the method body was defined, all that they care is that when they have an IFoo, that it has a method with the signature void Bar() that can be called, as I showed earlier, inheritance must include all interfaces, so there is no need to declare them again.
The answer is No. There is no difference.
The Class Derived inherits from Base and Base in turn inherits from IFoo.
So, there is no necessity for you to "Implement" both Base and IFoo when defining the class Derived.
The hierarchy is established when you are defining the class Base:
public abstract class Base : IFoo
and continued when you define Derived as below:
public abstract class Derived : Base
The only problem may arise when you "Remove" Base from the hierarchy by redefining the Base class by removing the : IFoo implementation from the Base class definition as below:
public abstract class Base
The bottom line is: , IFoo is redundant and is therefore not necessary.
Is there anyway to cast\convert an object to an inherited type directly?
class Base
{
void Process()
{
Base obj = new Derived1();
}
}
class Derived1 : Base
{
}
class Derived2 : Base
{
}
How can i covert the object obj to type of Derived2 without intializing or creating a new instance of Derived2?
From your example you cannot change an object from Derived1 to Derived2. Your code is creating a new instance of Derived1 into an object type of Base this is fine as Derived1 will have the same signature as Base. However Base does not have the same signature as Derived1 and you are not able to convert to an inherited type. Although Derived1 has a base class of Base does not ensure the signatures are the same.
This is also true in user defined conversions using implicit or explicit operators. You cannot write your own conversions from a base class as this would provide multiple valid conversions.
The only way you can convert Base to Derived2 (or another derived class) is to create a new reference of Derived2 and copy your properties to this new class. However in a real world situation this is not only time consuming, but typically a flaw in your design process.
In most cases you invoke a method which returns an object of a specific type. For example Base (which really has not methods or properties) should define how the object acts and the common properties and methods for that object. Where Derived1 and Derived2 can build on this common signature. Your design here is quite flexible but in a common scenario you could essentially re-write your objects similar to the example below. Where you will notice there is not conversions required.
First define an interface for the base class. Although this is not required adds a concrete level of uniformity between your classes (again not required).
interface IBase
{
string Name { get; set; }
void DoWork();
}
This simply defines an interface with one property and one method. Next write your simply base class as:
class Base : IBase
{
string name = "Base Class: ";
public virtual string Name
{
get { return this.name; }
set { this.name = value; }
}
public virtual void DoWork()
{
//Base class does no work...
}
}
The base class Base inherits from IBase and implements both the method and the property from the interface. In this example I also marked the property and method as virtual https://msdn.microsoft.com/en-us/library/9fkccyh4.aspx so any class that inherits from Base may override the member. So in this class the name is set (using a backing field) and has implemented the DoWork method which actually does nothing.
Next I define another class Derived1 which inherits from Base.
class Derived1 : Base
{
public override void DoWork()
{
this.Name = "Derived 1 did some work.....";
}
}
Now Derived1 inherits from Base and Base inherits the interface IBase. Base has defined the interface IBase and with the virtual keyword on both the method and the property. This means that Derived1 may override a member of Base (but doesnt have too)... The Derived1 class will now override the method DoWork and set the string Derived 1 did some work.... to the property Name.
We can then define a second class that inherits from Base as Derived2
class Derived2 : Base
{
string name;
public override string Name
{
get { return this.name; }
set { this.name = value; }
}
public override void DoWork()
{
this.Name = base.Name + " - Derived 2 did some work.....";
}
}
Just like before the new class Derived2 inherits from Base and in this instance is overriding both the property Name and the method DoWork however in this instance the do work method is access the property Name from the base class by using the base keyword. This essentially sets the name of Derived2 to the name of the base class Base and appends ' - Derived 2 did some work.....'.
Now this doesnt actually answer your question as you cant convert Derived2 to Derived or Derived2 to Base however provides the signature to build your classes against.
Now to use this in a real world we (as said before) execute methods or receive events that return our object type.
class Program
{
static void Main(string[] args)
{
var baseObj = getBase();
baseObj.DoWork();
Console.WriteLine("Base Name:" + baseObj.Name);
var d1 = getDerived1();
d1.DoWork();
Console.WriteLine("Derived 1 Name:" + d1.Name);
var d2 = getDerived2();
d2.DoWork();
Console.WriteLine("Derived 2 Name:" + d2.Name);
Console.ReadKey();
}
static IBase getBase()
{
return new Base();
}
static IBase getDerived1()
{
return new Derived1();
}
static IBase getDerived2()
{
return new Derived2();
}
}
As seen below we have 3 methods that return an instance of IBase these instances will all have matching signatures as they all inherit from the same interface. However in each method we are constructing new objects of different types. When the method DoWork is executed for each object the underlying methods are called on each object type.
Now this may be a long winded way of saying it can't be done but hopefully this shows you how you could achieve what are looking for by modifying how you define your objects.
Cheer
You cant do it, simply because Derived1 is not Derived2 (Derived1 != Derived2).
A good analogy would be, your base can be classified as a Fruit, and Derived1 and Derived2 can be Apple and Banana. In a bigger context, yes they're in the same categorization as a fruit. But you cant convert a banana to an apple and vise versa.
What you can do though is create your own converter, here is a quick mockup i created to get you started.
public static class ObjectConverter<T>
{
public static TTo Convert<TFrom, TTo>(TFrom value)
where TFrom : T
where TTo : T, new()
{
TTo result = new TTo(); // creates an instance of the target type
var baseProperties = value.GetType().GetProperties() // gets all properties
.Where(x => x.DeclaringType == typeof(T)); // based on target type
foreach (var prop in baseProperties)
{
prop.SetValue(result, prop.GetValue(value)); // sets value to the target
}
return result;
}
}
And consume like this.
Base item = new Derived1(); // base object
item.Age = 18; // properties existing on the base
item.Name = "Sasha";
Derived2 convertedItem = ObjectConverter<Base>.Convert<Derived1, Derived2>(item as Derived1);
I was looking for something like this. And the state design pattern fulfills it
http://www.codeproject.com/Articles/489136/UnderstandingplusandplusImplementingplusStateplusP
While attempting to override the explicit interface implementation of the ICollection<T>.IsReadOnly property from the Collection<T> class, I came across some documents stating that explicit interface member implementations cannot be overridden because they cannot have modifiers such as virtual or abstract. On MSDN they even go as far as specifying how to make an explicit interface member implementation available for inheritance by creating another abstract or virtual member which is called by the explicit interface member implementation. No problems so far.
But then I wonder: Why is it possible in C# to override any explicitly implemented interface member just by specifying the interface explicitly?
For example, suppose I have a simple interface like this, with a property and method:
public interface IMyInterface
{
bool AlwaysFalse { get; }
bool IsTrue(bool value);
}
And a class A which implements the interface explicitly, and has a method Test() which calls its own interface member implementation.
public class A : IMyInterface
{
bool IMyInterface.AlwaysFalse
{ get { return false; } }
bool IMyInterface.IsTrue(bool value)
{ return value; }
public bool Test()
{ return ((IMyInterface)this).AlwaysFalse; }
}
As you can see, none of the four members are virtual or abstract, so when I define a class B like this:
public class B : A
{
public bool AlwaysFalse
{ get { return true; } }
public bool IsTrue(bool value)
{ return !value; }
}
Then you'd expect an instance of B cast to A to behave like A. And it does:
A a = new A();
Console.WriteLine(((IMyInterface)a).AlwaysFalse); // False
Console.WriteLine(((IMyInterface)a).IsTrue(false)); // False
Console.WriteLine(a.Test()); // False
A b = new B();
Console.WriteLine(((IMyInterface)b).AlwaysFalse); // False
Console.WriteLine(((IMyInterface)b).IsTrue(false)); // False
Console.WriteLine(b.Test()); // False
Now comes the catch. Create a class C which is an exact copy of B except for one thing in the class declaration:
public class C : A, IMyInterface
{ /* ... same as B ... */ }
Now an instance of C, when cast to A, doesn't behave like A but like C:
A c = new C();
Console.WriteLine(((IMyInterface)c).AlwaysFalse); // True
Console.WriteLine(((IMyInterface)c).IsTrue(false)); // True
Console.WriteLine(c.Test()); // True
Even the Test() method now calls the overridden method in C! Why is this?
This has nothing to do with explicit interface implementation; it's simply a consequence of the general rules of inheritance and interface mapping: you would see exactly the same results if type A provided an implicit, rather than explicit, implementation of IMyInterface.
Type B inherits from type A. Nothing is overridden.
B provides its own AlwaysFalse and IsTrue members but they don't implement IMyInterface; The implementation of IMyInterface is provided by the members inherited from A: when an instance of type B is cast to IMyInterface then it behaves in exactly the same way as an instance of type A because A is providing the members that implement the interface.
Type C inherits from type A. Again, nothing is overridden.
C provides its own AlwaysFalse and IsTrue members but this time those members do implement IMyInterface: when an instance of type C is cast to IMyInterface then the members of C provide the interface implementation rather than those of A.
Because type A implements IMyInterface explicitly the compiler doesn't warn that the members of B and C are hiding the members of A; In effect those members of A were already hidden due to the explicit interface implementation.
If you changed type A to implement IMyInterface implicitly rather than explicitly then the compiler would warn that the members of B and C are hiding, not overriding, the members of A and that you should ideally use the new modifier when declaring those members in B and C.
Here are some relevant bits from the language specification. (Sections 20.4.2 and 20.4.4 in the ECMA-334 spec; sections 13.4.4 and 13.4.6 in the Microsoft C#4 spec.)
20.4.2 Interface mapping
The implementation of a particular
interface member I.M, where I is
the interface in which the member M
is declared, is determined by
examining each class or struct S,
starting with C and repeating for
each successive base class of C,
until a match is located.
20.4.4 Interface re-implementation
A class that inherits an interface
implementation is permitted to
re-implement the interface by
including it in the base class list. A
re-implementation of an interface
follows exactly the same interface
mapping rules as an initial
implementation of an interface. Thus,
the inherited interface mapping has no
effect whatsoever on the interface
mapping established for the
re-implementation of the interface.
I am creating an object structure and I want all sub classes of the base to be forced to implement a method.
The only ways I could think of doing it were:
An abstract class - Would work but the base class has some useful helper functions that get used by some of the sub classes.
An interface - If applied to just the base class then the sub classes don't have to implement the function only the base class does.
Is this even possible?
N.B. This is a .NET 2 app.
You can have abstract methods in a class with other methods that are implemented. The advantage over an interface is that you can include some code with your class and have the new object be forced to fill in the details for the abstract methods.
public abstract class YourClass
{
// Your class implementation
public abstract void DoSomething(int x, int y);
public void DoSomethingElse(int a, string b)
{
// You can implement this here
}
}
An abstract class - Would work but the
base class has some useful helper
functions that get used by some of the
sub classe
An abstract class doesn't require all functions it provides to be abstract.
abstract class Base {
public void Foo() {} // Ordinary method
public virtual void Bar() {} // Can be overridden
public abstract void Xyz(); // This one *must* be overridden
}
Note that if you replace public with protected, the marked method will be only visible to base classes and subclasses.
An interface - If applied to just the
base class then the sub classes don't
have to implement the function only
the base class does.
This is not entirely correct. If the base class is abstract, you can mark methods that belong to the interface as abstract, and force the implementation in the subclasses.
That brings an option you didn't mention: to use both. You have an IFoo interface, and a FooBase abstract base class the implements it, or part of it. This provides subclasses with a "default" implementation of the interface (or part of it), and also lets you inherit from something else and still implement the interface, or if you want to implement the interface but not inherit the base class implementation. An example might help:
// Your interface
interface IFoo { void A(); void B; }
// A "default" implementation of that interface
abstract class FooBase : IFoo
{
public abstract void A();
public void B()
{
Console.WriteLine("B");
}
}
// A class that implements IFoo by reusing FooBase partial implementation
class Foo : FooBase
{
public override void A()
{
Console.WriteLine("A");
}
}
// This is a different class you may want to inherit from
class Bar
{
public void C()
{
Console.WriteLine("C");
}
}
// A class that inherits from Bar and implements IFoo
class FooBar : Bar, IFoo
{
public void A()
{
Console.WriteLine("Foobar.A");
}
public void B()
{
Console.WriteLine("Foobar.B");
}
}
Yes, and if all the classes you need to do this for are logically subclasses of an existing abstract base class, then add an abstract method to the base class... This is better than an interface because it allows you to add implementation later (by changing abstract base class method to virtual method with a default implementation), if/when it turns out that, say, eight of ten derived classes will have the same implementation, and say, only two of them differ...
EDIT: (based on thread in comments below) The base class must be declared as abstract to do this... You can't have an abstract method in a non-abstract class because a non-abstract class can be instantiated, and if an instance of it was created, there wouldbe NO implementation for that method. So this is illegal. By declaring the base as abstract, you inhibit instantiation of the class. Then, only non-abstract derived classes can be instantiated, where, (because the base method is abstract) you MUST add an implementation for that method.
And full worker sample with params (.netcore 2.2):
class User{
public string Name = "Fen";
}
class Message{
public string Text = "Ho";
}
// Interface
interface IWorkerLoop
{
// Working with client message
string MessageWorker(string msg);
}
// AbstractWorkerLoop partial implementation
public abstract class AbstractWorkerLoop : IWorkerLoop
{
public User user;
public Message msg;
// Append session object to loop
public abstract AbstractWorkerLoop(ref User user, ref Message msg){
this.user = user;
this.msg = msg;
}
public abstract string MessageWorker(string msg);
}
// Worker class
public class TestWorkerLoop : AbstractWorkerLoop
{
public TestWorkerLoop(ref User user, ref Message msg) : base(user, msg){
this.user = user;
this.msg = msg;
}
public override string MessageWorker(string msg){
// Do something with client message
return "Works";
}
}