【问题标题】:I need Implement interface some methods only我只需要实现接口一些方法
【发布时间】:2013-04-10 07:09:17
【问题描述】:

在我的项目中有一个界面。在接口中有很多方法。我们公司其他开发人员将接口继承到某些类中,并实现我需要的所有方法天气只实现某些方法。那一次我遇到了一些错误。 “不实现接口成员”。我怎么解决这个问题? 例如:-

public interface IComplianceRepository
    {
        IList<ComplianceModel> LoadComplianceModel(Guid userId);
        bool CreateCompliance(ComplianceModel complianceModel);
        IList<ComplianceType> LoadComplianceType();
        IList<ComplianceStatu> LoadComplianceStatus();
        IList<UserDetails> LoadUsersBySchoolId(int schoolId);
        Compliance GetComplianceByComplianceId(int complianceId);
        bool UpdateCompliance(ComplianceModel complianceModel);
        UserProfile GetUserProfileDetails(Guid userId);
        FinancialCompliance GetFinancialComplianceByComplianceId(int ComplianceId);
        void GetComplianceModelByComplianceId(ComplianceModel complianceModel, int complianceId);
    }

更多的开发人员使用上述接口并实现了 all 方法。但我不想实现以下方法

    IList<ComplianceModel> LoadComplianceModel(Guid userId);
    bool CreateCompliance(ComplianceModel complianceModel);

我该如何解决这个问题?

【问题讨论】:

  • 制作两个独立的接口?接口是一种契约,如果你尝试使用一个实现了接口的类但未能提供两种方法的实现,而有人试图调用它,会发生什么?
  • 如果很难改变当前的接口并且你不需要实现那些方法,看起来你只需要实现它们然后抛出一个未实现的异常或者返回一个null。
  • ComplianceStatu - 使用实体框架? :-P 无论如何,如果您不必实现整个接口来实现您的目标,那么接口就太宽泛了。将其拆分为多个接口,以便每个接口仅包含符合其描述的方法。另一种方法是实现方法,但从那里抛出 NotImplementedException ...
  • @Dennis Rongo 我觉得你的想法不是好的做法
  • 这是接口隔离的理想方案。请参考这里的设计原则(oodesign.com/interface-segregation-principle.html)你需要隔离合约,不要把所有的鸡蛋放在一个篮子里。

标签: c# asp.net oop interface


【解决方案1】:

你不能。 Interface 存在的唯一原因是整个合约必须在实现它的类中实现。

【讨论】:

  • 也就是说,当您确定没有调用某些方法时,处理的常用方法是实现这些方法并在它们上抛出NotImplementedException然而,它是让您的类中的这些方法在生产代码中使用的不好的做法(您显然在您的类中实现该接口,因此应该拆分正确的接口,或者让它们从不太复杂的接口继承)跨度>
【解决方案2】:

如果您不能或不想更改接口,则应实现这些方法并抛出NotSupportedException。我建议为此使用显式接口继承,这样虚拟方法就不会出现在类中。

void IList<ComplianceModel> IComplianceRepository.LoadComplianceModel(Guid userId)
{
    throw new NotSupportedException();
}

作为 BCL 中的示例,您可以查看 ReadOnlyCollection.ICollection.Add Method。这是一个显式接口实现,它会抛出NotSupportedException。这也是糟糕设计的一个例子,证明了 .net 4.0 中缺少 IReadOnlyList&lt;T&gt; 接口。


真正的解决方案是重构您的代码。具有您完全实现的较小接口。看看Interface segregation principle

接口隔离原则 (ISP) 指出不应强迫任何客户端依赖它不使用的方法。 ISP 将非常大的接口拆分成更小、更具体的接口,这样客户只需了解他们感兴趣的方法即可。

【讨论】:

  • 只是为了迂腐,即使你抛出NotSupportedException 你仍然在实现该方法。它没有做任何有用的事情,但它确实有一个实现。根本没有办法不实现该方法。
  • @Servy 嗯?这与我的回答有何矛盾?
  • 好像没有。我虽然你有一个“或抛出一个 NotSupportedException”而不是一个“和”。
  • 虽然回想起来肯定存在协变 IReadableList&lt;out T&gt;IDataSink&lt;in T&gt; [其 Feed 方法将转换为 List.Add),但包含可能不适用于的方法的方法每个实例,连同将指示哪些此类方法可用于每个实例的查询,有时可能是一个很好的实例。例如,如果IEnumerable 包含EaseOfCounting 属性[返回标志枚举] 以及Count 属性,则无需尝试将枚举类型转换为ICollection 来获得计数。跨度>
  • IList&lt;T&gt; 在这方面最大的问题是没有足够的查询来指示给定实例可以做什么。例如,给定IList&lt;Car&gt; myList; Car myCar1,myCar2;,即使myList.Count 是10,唯一确定myList[0] = myCar1; 是否成功的方法是尝试它,看看它是否会引发异常[即使第一次赋值成功,@ 987654340@ 可能仍会抛出异常]。
【解决方案3】:

创建两个接口,父级和子级。 父母会得到你想要的,孩子也会有其他的。

public interface Parent {
    // parent methods here
}

public interface Child : Parent{
    // child methods here
}

【讨论】:

    【解决方案4】:

    如果一个类实现了一个接口,它必须实现该接口上的所有功能。接口是一种功能契约,因此任何声称满足该契约的东西都必须实际这样做。现在,您不必有意义地实施该合同中的所有内容。例如,对于您知道不会使用的方法,执行此操作的标准方法是:

    public void SomeMethodIKnowIWontUse()
    {
        throw new NotSupportedException();
    }
    

    因此,如果该方法曾经被实际使用过,那么它将引发异常。 (当你认为它不会被使用时,这表明你错了,你应该实现它。)

    请记住,这会很快导致“代码异味”。如果您有很多不需要实现的对象成员,那么显然设计是错误的......

    这里的另一种可能是界面设计不正确。也许它试图为太多人提供太多东西?这可能违反了Single Responsibility Principle。以这个接口为例:

    public interface CatchAll
    {
        void FunctionForOneResponsibility();
        void FunctionForCompletelyDifferentResponsibility();
    }
    

    使用非常做作的名称,很明显这个接口有太多的责任。应该是这样的:

    public interface OneResponsibilitySatisfier
    {
        void FunctionForThisResponsibility();
    }
    
    public interface AnotherResponsibilitySatisfier
    {
        void FunctionForThisOtherResponsibility();
    }
    

    没有规则说你需要有几个接口,或者一个接口需要有很多成员。每个人都应该为其职责提供一个有意义的功能合同,仅此而已。如果碰巧你有一个类可以同时满足这两种职责,那么它可以同时实现这两种接口:

    public class CrossCuttingObject : OneResponsibilitySatisfier, AnotherResponsibilitySatisfier
    {
        public void FunctionForThisResponsibility() { }
        public void FunctionForThisOtherResponsibility() { }
    }
    

    【讨论】:

    • 你把NotSupportedExceptionNotImplementedException搞混了
    • @CodesInChaos:我想这可能取决于类型的概念上下文。是否因为该实现不执行该功能而不受支持? (在这种情况下,我质疑接口的设计。)或者它没有实现是因为该实现还没有构建它的需要?无论哪种方式,我都会更新答案。
    【解决方案5】:

    接口作为接口的实现者和用户之间的契约而存在。用户/消费者要求实现所有方法。首先,问问自己没有这些方法的实现是否仍然有用。如果是这样,问问自己是否需要从这个接口继承。

    如果经过这个反思,你仍然有正当理由实现这个接口而不实现所有方法,你可以创建存根方法:

    IList<ComplianceModel> LoadComplianceModel(Guid userId)
    {
       throw NotSupportedException();
    }
    

    或者,更危险,但破坏性可能更小:

    IList<ComplianceModel> LoadComplianceModel(Guid userId)
    {
       return null;
    }
    

    【讨论】:

    • 应该是NotSupportedException 而不是NotImplementedExceptionNotSupported 表示故意不支持。 NotImplemented 表示您还没有编写代码。它本质上是一个待办事项。
    【解决方案6】:

    这是接口隔离的理想方案。请在此处参考此设计原则(oodesign.com/interface-segregation-principle.html)您需要隔离合约,不要将所有鸡蛋放在一个篮子里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      • 2017-12-25
      • 2013-02-26
      • 2014-06-15
      • 1970-01-01
      相关资源
      最近更新 更多