如果接口也是成员,则提取接口隐藏成员的详细信息

时间:2019-09-27 08:56:41

标签: c#

我有一个此类Project,我想从中提取接口,因为我们将要处理不同类型的项目。 Project的属性之一称为Data

class Project {
    public Data D {get;}
    public void SomeSpecificMethodReferencingData() 
    { 
      D.SomeSpecificMethod(); 
    }
}

class Data {
   public void SomeGenericMethod() { }
   public void SomeSpecificMethod() { }
}

现在,也需要将Data提取为一个接口(但仅定义SomeGenericMethod()。我目前正在使用它:

interface IProject {
    IData D {get;}
}

interface IData {
    void SomeGenericMethod();
}

class Data : IData {
    public void SomeGenericMethod() { }
    public void SomeSpecificMethod() { }
}

class OtherData : IData {
    public void SomeGenericMethod() { }
    public int SomeOtherSpecificMethod(float someArgument) { }
}

class Project : IProject {
    public IData D { get; }
    public void SomeSpecificMethodReferencingData()
    { 
      D.SomeSpecificMethod(); // this does not work!
      (D as Data).SomeSpecificMethod(); // this looks stupid!
    }
}

class OtherProject : IProject {
    public IData D { get; }
    public void SomeOSpecificMethodReferencingOtherData()
    {
       var i = D.SomeOtherSpecificMethod(14.0f); // this does not work!
       var i = (D as OtherData).SomeOtherSpecificMethod(14.0f); // this looks stupid!
    }
}

我遇到的问题是在Project类中,我引用了SomeSpecificMethod。但是,当我提取Data的接口时,我首先必须从IData强制转换它,以便能够引用特定的方法。这不是可取的,因为IData总是该项目的Data实例。构建OtherProject时,我将为其创建一个OtherData,以便获得xxxProject和xxxData实现对。

是否存在某种设计模式可帮助我构建相关和引用的类对?像抽象工厂一样,但是更好吗?

3 个答案:

答案 0 :(得分:3)

您可以使用泛型:

interface IProject<T> where T: IData {
    T D {get;}
}

现在您的不同项目是:

class Project : IProject<Data> 
{
    public Data D { get; }
    public void SomeSpecificMethodReferencingData()
    { 
        D.SomeSpecificMethod();  // D is of type Data
    }
}

class OtherProject : IProject<OtherData> {
    public OtherData D { get; }
    public void SomeOSpecificMethodReferencingOtherData()
    {
         D.SomeOtherSpecificMethod(14.0f); // D is of type OtherData
    }
}

答案 1 :(得分:1)

您可以拥有3个独立的界面:

interface IData:ISpecificData, IGenericData
    {    
    }
    interface ISpecificData
    {
        void SomeSpecificMethod();
    }
    interface IGenericData
    {
        void SomeGenericMethod();
    }

当您仅需要一种方法时,就只能使用一个接口,而当您同时需要两种方法时,就可以使用IData

答案 2 :(得分:1)

在Project类中,您引用的是Data类的SomeSpecificMethod。

您没有使用IData界面中的任何内容-因此在IData类中使用Project毫无意义。

可以像您的示例中那样进行操作,并且可以运行-但这是“错误的方式”。

  (D as Data).SomeSpecificMethod(); // this looks stupid!

它看起来很愚蠢-但出于其他原因。如果D不是Data而是OtherData怎么办?它将在编译时完全正确,但是会在运行时爆炸!

相关问题