Why should I explicitly implement a member of an interface of an object of a type when the member has already been implemented with another type?

Consider the following example:

namespace Test { interface IContract : IContract<object> { } interface IContract<T> { void Definition(T data); } public class SomeClass : IContract, IContract<SomeContractClass> { public void Definition(SomeContractClass data) { // ... } } public class SomeContractClass { } } 

I thought I satisfied the interface by providing Definition(SomeContractClass data) , because, as stated in MDSN :

In the C # unified type system, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from an object.

But instead, the compiler asks me to explicitly define it:

Error 1 'Test.SomeClass' does not implement the interface member 'Test.IContract.Definition (object)'

+4
source share
2 answers

You are implementing the IContract interface.

If we smooth out the inheritance hierarchy, we can see that IContract looks something like this:

 interface IContract { void Definition(object data); } 

You do not provide a method that matches the signature of void Definition (object data) . Instead, the method you supply accepts SomeContractClass . Therefore, you receive an error message.

However, I believe that the main problem is that your class implements both IContract and IContract<T> (which is the same as saying IContract<object> and IContract<T> ). I think your design needs some work ...

+8
source

I will make an analogy with your line.

You have a small company that repairs small cars.

You sign a contract with a government that needs a repair service for any type of vehicle in their diplomatic fleet (airplanes, boats, large trucks and small cars).

You lied / made a small mistake the moment you generalized that

1) since you are successfully implementing

 void Repair(SmallCar vehicle) 

2) and because

 class SmallCar : Vehicle { } class Airplane : Vehicle { } class Boat : Vehicle { } class BigTruck : Vehicle { } 

somehow, the union of points (1 + 2) => point 3, which reads:

3) The government can safely refer to your small company as โ€œGuys who are repairing somethingโ€ and someday think that it is a good idea to ask your company to help them like this:

 Airplane protocolPlane = new Airplane(); yourCompany.Repair(protocolPlane); 

which, of course, is not so: (1 + 2) does not imply (3)

It's good that this ended with a compiler error, not an exception. Thus, you will learn early on a small problem in architecture.

EDIT

In your code, if you decide that you really need to implement both interfaces in the SomeClass class, and you do not know how to do this, you can use an explicit interface implementation as follows:

 public class SomeClass : IContract, IContract<SomeContractClass> { // Method of IContract<SomeContractClass> public void Definition(SomeContractClass data) { Console.WriteLine("Processing a SomeContractClass instance"); // ...etc } // Method of IContract hence of IContract<object> void IContract<object>.Definition(object data) { if (data is SomeContractClass) this.Definition(data as SomeContractClass); else { string descriptor = (null == data) ? "A null reference" : "An instance of " + data.GetType().Name"; Console.WriteLine("Processing something other than a SomeContractClass instance: " + descriptor); // ...etc } } } 

Thus, you will get the following results:

 class Program { public static void Main(string[] args) { SomeClass someInstance = new SomeClass(); IContract<SomeContractClass> first= someInstance; IContract second = someInstance; someInstance.Definition(new SomeContractClass()); // prints out "Processing a SomeContractClass instance" first.Definition(new SomeContractClass()); // prints out "Processing a SomeContractClass instance" second.Definition(new SomeContractClass()); // prints out "Processing a SomeContractClass instance" second.Definition( "something else" ); // prints "Processing something other // than a SomeContractClass instance: An instance of String" second.Definition( 123 ); // prints "Processing something other // than a SomeContractClass instance: An instance of Int32" first.Definition( true ); // doesn't compile saying that bool can't be converted to SomeContractClass } } 

END OF EDITING

+3
source

All Articles