【问题标题】:C# Interface implementation: doing the right thingC#接口实现:做正确的事
【发布时间】:2010-10-18 09:30:15
【问题描述】:

我有一个假设的经销商可以提供一些服务;所有服务都是相同的:它们威胁一些 IRequest 数据,加上一些 IExtraData,并提供 IResponse。

请阅读此代码(使用 C# 2.0):

    public interface IResellerService<in TIn, in TInExtra, out TOut, in TOutExtra>
    where TIn : IRequest
    where TInExtra : IExtraData
    where TOut : IResponse
    where TOutExtra : IExtraData
{
    #region Properties
    string Code
    {
        get;
        set;
    } 

    //Some other simple properties here...
    #endregion

    //Some methods there...
}

//Need a collection of IResellerServices; using a IList just to have Add facility
public interface IResellerServices : IList<IResellerService<IRequest, IExtraData, IResponse, IExtraData>>
{
    IResellerService<IRequest, IExtraData, IResponse, IExtraData> Get(string code);
    void Update(IResellerService<IRequest, IExtraData, IResponse, IExtraData> reseller);
    void Delete(string code);
    void Disable(string code);
}

public class AvailabilityService : IResellerService<AvailabilityDocumentRequest, AvailabilityInputExtraData, AvailabilityDocumentResponse, AvailabilityOutputExtraData>
{
    //Here the interface implementation;


    /* 
     NOTE IResellerService declaration
     AvailabilityDocumentRequest : IRequest
     AvailabilityInputExtraData : IExtraData
     AvailabilityDocumentResponse : IResponse
     AvailabilityOutputExtraData : IExtraData
     */
}


[Serializable]
public class Reseller : IReseller
{
    #region Properties
    public string Code
    {
        get;
        set;
    }

    [XmlArray("Services")]
    [XmlArrayItem("Service")]
    public IResellerServices Services
    { get; set; }

    //Some other simple properties here...
    #endregion

    //Some methods there...
}

//Just to make me explain...
void Main()
{
    Reseller res = new Reseller;
    //Fill reseller properties here...
    //...

    AvailabilityService service = new AvailabilityService();
    //Fill service properties here...
    //...

    //ERROR!
    res.Add(service); //<-- ERROR! Need to cast my AvailabilityService to IResellerService<IRequest, IExtraData, IResponse, IExtraData>

    //OK
    res.Services.Add(service as IResellerService<IRequest, IExtraData, IResponse, IExtraData>);
}

好吧,我可能错过了继承或接口实现的一些基本概念,但我做错了什么?

希望你能理解我的需要。

【问题讨论】:

  • 上面的代码不会在 C# 2.0 中工作 - 它使用了泛型变量,它只在 C# 4.0 中引入。
  • 您应该阅读 .net 4.0 中引入的通用接口中的方差概念
  • 显示 IReseller.Add 或 Reseller.Add 声明
  • 谢谢你们,你们是对的。回到 C# 2.0 让我有点困惑...... :-S

标签: c# .net inheritance interface


【解决方案1】:

我认为您将在这里遇到的问题是,尽管以这种方式将接口放在一起很好,但如果您有一个接口,那么您确实需要一些东西来使用该接口。您还没有这样做,您已经通过实现该接口专门化了一个类型,但是哪些类型将直接使用该接口作为输入呢?这是一个例子:

public interface IService<TModel>
{
  TModel Get(string id);
}

public class MyService : IService<MyModel>
{
  public MyModel Get(string id)
  {
    // Work
  }
}

var service = new MyService();
var model = service.Get("something");

上面,虽然我已经为服务定义了一个接口,但我实际上并不依赖于代码中的那个服务。我仍然依赖IService&lt;TModel&gt;:MyService的具体实现。

我的代码不应该关心MyService 是什么,它应该只关心它是否可以支持IService&lt;TModel&gt; 定义的操作。如果我们重构了这个:

public class ModelFactory<TModel>
{
  IService<TModel> _service;

  public ModelFactory(IService<TModel> service)
  {
    _service = service;
  }

  public TModel Get(string code)
  {
    return _service.Get(code);
  }

}

现在我有一个可以使用我的接口的类,并允许我将实现与我的代码分离:

var factory = new ModelFactory<MyModel>(new MyService());
var model = factory.Get("something");

通常您会使用 IoC/DI 来注入依赖项,但我希望这是一个清晰的示例。

【讨论】:

  • Matthew,您的 Factory 解决方案是一个不错的解决方案。午餐后(在意大利这里是中午半点:-))我会试一试。谢谢!
猜你喜欢
  • 2018-05-20
  • 1970-01-01
  • 2022-01-23
  • 2017-12-13
  • 1970-01-01
  • 2017-08-19
  • 2016-03-27
  • 2016-02-15
  • 1970-01-01
相关资源
最近更新 更多