当类型对象的接口成员已经用另一个类型实现时,为什么我必须显式实现该成员

本文关键字:实现 成员 类型 为什么 另一个 接口 对象 | 更新日期: 2023-09-27 18:01:06

考虑以下示例:

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 { }
}

我想我会通过提供Definition(SomeContractClass data)来满足接口,因为正如MDSN:中所述

在C#的统一类型系统中,所有类型,预定义的和用户定义的、引用类型和值类型,直接继承或间接来自对象。

但编译器要求我明确定义它:

错误1"Test.SomeClass"未实现接口成员'测试.IContract.Definition(object('

当类型对象的接口成员已经用另一个类型实现时,为什么我必须显式实现该成员

您正在实现接口IContract

如果我们将继承继承制压平,我们可以看到IContract本质上看起来是这样的:

interface IContract
{
    void Definition(object data);
}

您没有提供与签名void Definition (object data)匹配的方法——您提供的方法采用SomeContractClass。因此,您将得到所述的错误消息。

然而,我认为根本问题是您的类同时实现了IContractIContract<T>(这与IContract<object>IContract<T>相同(。我认为你的设计需要一些工作。。。

我将对你的情况进行一点类比。

你有一家修理小型汽车的小公司。

你与政府签订了一份合同,政府需要为其外交车队中的任何类型的车辆(飞机、船只、大卡车和小型汽车(提供维修服务。

你在概括的那一刻就撒谎了/犯了一个小错误

1( 自从你成功实施

void Repair(SmallCar vehicle) 

2( 因为

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

不知何故,点(1+2(的组合=>点3,其状态为:

3( 政府可以放心地称你的小公司为"修理任何东西的人"有一天,请你的公司这样帮助他们是个好主意:

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

这当然不是真的:(1+2(并不意味着(3(

好在这最终是一个编译器错误,而不是运行时异常。通过这种方式,您可以更快地了解体系结构中的一个小问题。

编辑

在您的代码中,如果您决定确实需要在SomeClass类中实现这两个接口,但您不知道如何做到这一点,则可以使用如下显式接口实现:

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
        }
    }
}

这样,您将成功获得以下结果:

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
     }
}

编辑结束