Is it a breaking change that modifying the access modifier of a public property?
This depends on how strict you want to be about "breaking change".
One definition is: does it break the build or execution of the referring code.
Another is, can the other code determine that you made the change.
By the first definition, this is not a breaking change. By the second definition, it is a breaking change.
UPDATE: This question was the topic of my blog in January 2012. Thanks for the great question!
I assume that by "breaking change" you mean "when I recompile code that depended on this assembly, does code that used to compile still compile?"
By that definition, strictly speaking, yes, making a property setter public that used to be private is a breaking change. Suppose you have this code:
// Assembly Alpha
public class Charlie
{
public int P { get; private set; }
}
public class Delta
{
public int P { get; set; }
}
And then in another assembly that references Alpha:
// Assembly Echo
class Foxtrot
{
static void M(Action<Charlie> f) {}
static void M(Action<Delta> f) {}
static void Golf()
{
M(y=>{y.P = 123;});
}
}
You compile assembly Echo. Class Foxtrot has a method Golf which does overload resolution on M. M has two overloads; one that takes a action on Charlie and one that takes an action on Delta. If lambda parameter y is of type Charlie then the lambda body produces an accessibility error, and therefore that overload of M is not an applicable candidate. Overload resolution chooses the second overload and compilation succeeds.
Now you change assembly Alpha so that Charlie.P's setter is public. You recompile Echo. Now you get an overload resolution error because both overloads of M are equally valid and neither is better than the other. Compilation of Echo fails due to the change in Alpha. Your change to Alpha was a breaking change.
The question is not "is this a breaking change?" It clearly is; almost every change is some kind of breaking change. The question should be whether the breaking change will actually in practice break anyone, and if so, what is the cost of fixing the break compared to the benefit of the new feature?
It is a breaking change, in that it may cause existing code to no longer compile.
Some languages do not allow you to override a property without overriding all visible accessors. VB is such a language.
Say you have the following C# class:
namespace TestLibrary
public class A {
public virtual int X {
get { return 0; }
private set { Console.WriteLine("A.set_X called."); }
}
}
}
In a VB project that references your library, you have a class definition:
Class B : Inherits TestLibrary.A
Public Overrides ReadOnly Property X As Integer
Get
Return MyBase.X
End Get
End Property
End Class
Notice the ReadOnly
modifier on the property. This is required in VB, because you are only defining the getter. If you leave it out, you get a compile-time error:
Property without a 'ReadOnly' or 'WriteOnly' specifier must provide both a 'Get' and a 'Set'.
Now, remove the private
modifier from the setter in your C# class:
namespace TestLibrary
public class A {
public virtual int X {
get { return 0; }
set { Console.WriteLine("A.set_X called."); }
}
}
}
You will now get a compile-time error in your VB code:
'Public Overrides ReadOnly Property X As Integer' cannot override 'Public Overridable Property X As Integer' because they differ by 'ReadOnly' or 'WriteOnly'.
The same code that references your library does not compile after you make the change, so it is a breaking change.