C#与可选方法的接口

Nel*_*mel 39 c# versioning interface

我知道接口是契约,任何更改(甚至添加)都会破坏任何相关代码.但是,我可以发誓我曾经读过一些最近的.NET版本(3,3.5 ??)添加了一个可以应用于新接口成员的新属性.此属性允许版本控制和/或使成员可选.它应该是这样的:

interface ITest
{
    void MethodOne();

    [InterfaceVersion(2)]
    void MethodTwo();
}
Run Code Online (Sandbox Code Playgroud)

我为此寻找高低,但似乎无法找到它.我想知道我是否只是误解了我认为我读过的东西而且没有这样的东西.有人有任何见解吗?

ang*_*son 47

您应该创建两个接口:

interface ITest
{
    void MethodOne();
}

interface ITest2 : ITest
{
    void MethodTwo();
}
Run Code Online (Sandbox Code Playgroud)

这也可以清楚地说明哪个功能需要哪个版本的接口,因此您无需检查实现接口的类是仅实现一个方法还是两个方法.

  • 在 C# 8.0 中,现在可以利用默认实现来创建可选的接口方法。请参阅我的答案或此处:https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#default-interface-methods (2认同)

Leo*_*die 12

如果您的项目完全支持 C# 8.0,您可以使用“默认接口实现”,这使得该方法可以选择实现,如果您选择不实现它,则回退到默认实现。

interface ITest
{
    void MethodOne();

    public void MethodTwo()
    {
       //Empty default implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

以下 SDK 支持默认接口实现:

  • .NET 5 及更高版本
  • .NET Core 3.0 及更高版本
  • .NET 标准 2.1 及更高版本
  • Xamarin.iOS 13.0 及更高版本
  • Xamarin.Android 10.0 及更高版本
  • Xamarin.Mac 6.0 及更高版本
  • 单声道 6.0.0 及更高版本

未来支持

没有支持计划

  • .NET Framework 4.8.x 及更早版本

  • 在我看来,这是使用可选功能进行界面的新“正确”方法。但请注意,Unity 不支持这一点(唉)。至少在撰写本文时是这样。 (3认同)

Kil*_*fer 10

我没有看到这样的属性,但我想这是可能的.MSDN上的这篇文章通过使用overridesnew关键字来描述版本控制.

简而言之,C#配备了语言功能,允许派生类进化并仍然保持兼容性.此示例显示了纯粹的基于派生的关系,但基本实际上将实现版本所需的接口.让一个接口需要另一个(先前版本)接口与此方法相结合也是非常有用的.

创建需要另一个的接口的示例:

public interface IMyInterface
{
  void FirstMethod();
}

public interface IMySecondInterface : IMyInterface
{
  void SecondMethod();
}
Run Code Online (Sandbox Code Playgroud)

使用继承来保持兼容性的示例:

public class MyBase 
{
   public virtual string Meth1() 
   {
      return "MyBase-Meth1";
   }
   public virtual string Meth2() 
   {
      return "MyBase-Meth2";
   }
   public virtual string Meth3() 
   {
      return "MyBase-Meth3";
   }
}

class MyDerived : MyBase 
{
   // Overrides the virtual method Meth1 using the override keyword:
   public override string Meth1() 
   {
      return "MyDerived-Meth1";
   }
   // Explicitly hide the virtual method Meth2 using the new
   // keyword:
   public new string Meth2() 
   {
      return "MyDerived-Meth2";
   }
   // Because no keyword is specified in the following declaration
   // a warning will be issued to alert the programmer that 
   // the method hides the inherited member MyBase.Meth3():
   public string Meth3() 
   {
      return "MyDerived-Meth3";
   }

   public static void Main() 
   {
      MyDerived mD = new MyDerived();
      MyBase mB = (MyBase) mD;

      System.Console.WriteLine(mB.Meth1());
      System.Console.WriteLine(mB.Meth2());
      System.Console.WriteLine(mB.Meth3());
   }
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*ert 6

您是否正在考虑C#4中新的"无pia"功能?也就是说,我们允许您仅从PIA"链接"实际使用的界面部分,然后您可以跳过向您的客户发送PIA.如果您在几个不同的程序集中多次执行此操作,CLR会确定所有这些链接的部分接口在逻辑上是相同的类型,并统一它们.这样,您可以将实现接口的每种风格的对象从一个程序集传递到另一个程序集,这一切都可以正常工作.但是,创建"no pia"接口的原始接口必须相同.


Dav*_*ton 5

我知道没有这样的属性可以部分实现接口实现。您可以使用抽象类解决此问题,但是:

public abstract class Test
{
     public abstract void MethodOne();
     public virtual void MethodTwo() { }
}
Run Code Online (Sandbox Code Playgroud)

这将允许用户决定从Test继承时是否要重写MethodTwo,同时强制重写MethodOne。


Jor*_*oba 5

.NET框架中没有这样的属性.