问题
Suppose we have the class X
in version 1 of the assembly A.dll
:
class X {
SomeType Property { set; get; }
}
and then in version 2 of the assembly A.dll
:
class X {
SomeType Property { set; get; }
SomeType OtherProperty { set; get; }
}
Now suppose we have a second assembly B.dll
that loads A.dll
and uses X. Will the addition of the property OtherProperty
break the ABI? Will B.dll
fail to use A.dll
/X
? If not, would the order of the declarations make any difference? If the properties had been virtual, had it made any difference?
I guess I'm really asking: what are the general ABI rules? I know changing interfaces after they have been published is a bad thing, but I really would like to be able to add properties in some instances, without adding subclasses.
回答1:
Adding properties should be fine.
One case that will break is if you for example add something to the middle of an automatically numbered enum. For example if you have this code in your library:
enum Foo
{
Bar,
Qux
}
and you change it to this:
enum Foo
{
Bar,
Baz,
Qux
}
Then you will also need to recompile any code like this:
if (foo == Foo.Qux)
{
// ...
}
回答2:
The JIT compiler will spackle a lot of this over, also the source of the error message if the change was breaking.
You are however playing a very dangerous game called DLL Hell. The problem is not that they don't recompile their code, it is when they do. They will, eventually. If then there's a subtle mistake, somebody ran an old version of your installer, copied the wrong file, etcetera then all hell breaks loose. The code won't run and they'll have an impossible job figuring out why. This will happen long after you made the change, you won't have any way to guess what went wrong either and cannot help them.
Don't mess around with this, bump up [AssemblyFileVersion] and [AssemblyVersion]. Yes, they'll have to recompile when you change the latter one. Or use <bindingRedirect>
, which is fine too, now there's a traceable record of it.
Btw: this happened in the .NET Framework too. WaitHandle.WaitOne(int) got added in a service pack but without an [AssemblyVersion] change. Programmers targeted .NET 2.0 but their code wouldn't run when the target machine had the original 2.0 installed. Very painful.
回答3:
It won't break compatibility if is just used by the assembly B
. But it will break if the assembly B
defines a class which implements the interface, because that class doesn't implement the newly introduced property.
来源:https://stackoverflow.com/questions/4766891/c-sharp-interface-breakage-abi