繁体   English   中英

将.NET中的访问修饰符从共享组件中的私有更改为私有是一项重大更改吗?

[英]Is changing an access modifier in .NET from private to public in share component a breaking change?

让我们考虑一个理论例子

  • ApplicationA
  • SharedLibrary -> ClassA
  • Plugin

如果您在SharedLibrary更改ClassA ,请更新ApplicationA以使用新的SharedLibrary但不要更新Plugin 您仍然能够(通过Assembly.CreateInstance或MEF)加载Plugin吗?

在.NET中,从private -> public更改访问修饰符是一项重大更改吗?

本文似乎暗示即使添加某些内容也将是一项重大更改,但是谈论的是重载等,而不是修饰符。 https://blogs.msdn.microsoft.com/ericlippert/2012/01/09/every-public-change-is-a-breaking-change/

编辑Plugin使用了ShareLibrary类。 因此,提出要求的原因。

问候

是的, public private成员可以破坏构建。

考虑此类:

public class Test
{
    private int Method(int x = 0) => x;
    public int Method(int x = 1, int y = 2) => x + y;

    public int Foo => Method(0);
}

这段代码:

class Program
{
    static void Main()
    {
        Console.WriteLine(new Test().Method());
    }
}

这将编译OK,并打印3

现在,如果将Method()的私有重载公开,则上面的代码将不再编译。 您将得到以下编译错误:

Error   CS0121  The call is ambiguous between the following methods or properties: 
'Test.Method(int)' and 'Test.Method(int, int)'  

但是,关于您的插件问题-您未指定它是否使用SharedLibrary 如果不是,则更改SharedLibrary不会破坏插件。

如果确实如此,则可能会收到讨厌的运行时错误,具体取决于它的使用方式-但这实际上并不能保证会发生。


这是一个使用插件的示例,如果您将方法公开,该插件将在运行时中断。

首先,我们有一个共享的类库,其中包含以下类:

public class Test
{
    private int Method(int x = 0) => x;
    public int Method(int x = 1, int y = 2) => x + y;

    public int Foo => Method(0);
}

其次,我们有一个插件类,该类通过反射使用该库,如下所示:

public class Plugin
{
    public int Test()
    {
        var testClass = typeof(Test);
        var testInstance = Activator.CreateInstance(testClass);
        var method = testClass.GetMethod("Method");
        int result = (int)method.Invoke(testInstance, new object[]{1, 2});
        return result;
    }
}

现在,假设我们有一个使用共享类的应用程序,并且在其输出文件夹中还包含插件程序集DLL的副本:

static void Main()
{
    Console.WriteLine(new Test().Method(1, 2));

    var plugin       = Assembly.LoadFile(Path.GetFullPath("PluginLibrary.dll"));
    var testClass    = plugin.GetType("PluginLibrary.Plugin");
    var testInstance = Activator.CreateInstance(testClass);
    var method       = testClass.GetMethod("Test");
    int result       = (int) method.Invoke(testInstance, null);

    Console.WriteLine(result);
}

这样就可以了。

现在,假设您将private int Method(int x = 0)公开,并重新编译共享类库和使用它的应用程序,但不要重新编译插件-即您继续使用旧的插件DLL。

现在,如果您运行该程序,将得到一个“ Ambiguous match found异常。

这是一个示例,其中您通过公开一个甚至没有被该插件使用的方法来破坏了一个未更改的插件。

在您链接的网站上:一些明显的公共领域突破性变化是显而易见的:将公共方法变成私有方法

是的,这是一个重大变化,但是如果您在插件中不使用此类和方法,则不会破坏您的程序。 您可以更改体系结构以依赖接口,而不是插件中的实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM