Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用较少方法实现旧版本接口的对象_C#_.net_Interface_Clr_Il - Fatal编程技术网

C# 如何使用较少方法实现旧版本接口的对象

C# 如何使用较少方法实现旧版本接口的对象,c#,.net,interface,clr,il,C#,.net,Interface,Clr,Il,我在应用程序中有一个程序集,用于定义以下接口: public void Method1() 然后我有一个实现这个接口的汇编插件。它在运行时被发现并加载 之后,我修改了界面以包含一个新方法: public void Method1() public void Method2() 我创建了一个新的汇编插件,实现了新版本的界面 有没有办法只在应用程序上部署新接口和新插件?目前,客户端永远不会在第一个插件上调用Method2(),所以这应该不是问题(如果在任何时候在第一个插件上调用Method2,我

我在应用程序中有一个程序集,用于定义以下接口:

public void Method1()
然后我有一个实现这个接口的汇编插件。它在运行时被发现并加载

之后,我修改了界面以包含一个新方法:

public void Method1()
public void Method2()
我创建了一个新的汇编插件,实现了新版本的界面

有没有办法只在应用程序上部署新接口和新插件?目前,客户端永远不会在第一个插件上调用Method2(),所以这应该不是问题(如果在任何时候在第一个插件上调用Method2,我都可以抛出异常)

我原以为我能做到,但我得到了一个
TypeLoadException
说:

程序集“Provider2,版本=1.0.0.0,区域性=中性,PublicKeyToken=null”中类型“Provider2.Class2”中的方法“Method2”没有实现


(这是正确的,但由于没有调用Method2,所以不应该是问题)

您不应该修改该接口

接口通常以两种主要方式之一使用:

  • 它们完全在应用程序内部使用
  • 它们是公共的,因为其他人可以创建插件之类的东西来实现或使用接口
  • 在第一个选项中,您当然可以自由地使用它做任何您想做的事情,比如向它添加新方法。这是你自己的问题,如果这造成了许多编译器错误,你可以“轻松”修复这些

    在第二个选项中,永远不要修改该接口。相反,您应该使用新方法创建一个新接口,然后编写代码,使其同时支持旧接口和新接口

    当然,除非你想完全禁止旧的课程,否则你就会回到你想做的任何事情

    因此,这里的答案是,您不应该修改该接口。而是用新方法创建一个新接口,并支持旧版本和新版本

    无论何时更改接口,您都应该努力使用这种方法,这包括更多类型的更改,而不仅仅是添加一个方法

    如果您更改了接口的含义,或者修复了主要的非灾难性错误,那么您可能希望引入一个新接口,让旧接口拥有旧的错误。有些人可能编写了依赖于旧行为的代码,不管是好是坏,而您“修复”了这些代码可能会破坏以前的工作方式,即使编译器没有抱怨

    例如,假设您将比较结果传递给一个方法。您的文档说明,如果比较结果为
    ,则值为正值;如果比较结果为
    =
    ,则值为0

    然后,您突然发现您没有返回-1、0或+1,而是返回-N、0和+N,其中N是比较的副产品,例如
    a-B
    ,因此在下一个版本中,您将其更改为-1、0和+1

    有些代码可能依赖于这样一个事实,即这些值不仅表示比较的结果,而且确实是
    -N
    ,因此修复此问题会破坏代码

    当然,依赖未记录的行为总是不好的,但同样,您的客户很可能会因为代码正常工作而挂断电话,而您的更新破坏了它

    因为没有调用Method2,所以不应该是问题

    Net中的类型不是这样工作的。如果您的类声明它实现了一个接口,那么它只需实现该接口


    您所描述的与类似,而.Net不使用它。

    关于您的最后一部分:如果您决定保留返回的旧接口
    -N
    ,请记录它。不要继续仅仅声称它返回一个负数,因为如果你这样做,其他人(稍后将维护代码)可能不会注意到这是故意的。这甚至不是ducky键入。该类可以实现
    Swim()
    ,但它没有实现
    Quack()
    (因为这是后来添加到接口中的),因此即使通过duck键入,它也不是duck:)@hvd但是对于duck类型(“ducky”是一个拼写错误,虽然听起来不坏:-)),如果你不调用
    Quack()
    ,你就不会发现它实际上不是一个duck。啊,我明白你的意思了,我们讨论的是两个微妙不同的东西,它们都被称为“duck类型”。我说的是程序执行(伪代码)
    动态接口IDuck{void Swim();void Quack();}
    ,然后检查
    插件是否为IDuck
    ,这将失败。您正在谈论的程序正在执行
    ((动态)plugin).Swim()
    ,这将成功。谢谢。我不知道duck类型的概念,我想我可以直接从C#开始。无论如何,我不确定这是一个好主意还是在出现问题之前不提出异常。。。