Reputation: 22591
When updating a library, it's important to accurately communicate any breaking changes. Unfortunately there are a number of different kinds of breaking changes in C#, and some of them are quite subtle.
The obvious ones are things like changing the names of types or type members.
The subtle ones are things like adding a new default parameter (binary compatibility is broken, but source compatibility is preserved), or renaming a parameter (binary compatibility is maintained, but source compatibility is broken).
I am unsure about renaming generic parameters.
For example, is there a case where changing:
public class Foo<T>
{
public T Bar(){ /* something */ }
}
to
public class Foo<TMoreDescriptive>
{
public TMoreDescriptive Bar(){ /* something */ }
}
between releases of a library could break a consumer?
Upvotes: 4
Views: 1102
Reputation: 11080
Changing the name of a generic type parameter is no more a breaking change than changing the name of a method parameter is. According to the C# Programming Guide, generic types are replaced the moment the consumer instantiates the class with a generic type argument - at no point is the consumer given the original type parameter's name except via documentation or an IntelliSense-like feature.
The guide also mentions that generic type parameters are available via reflection - this is likely the only vector by which your consumer is able to programmatically inspect the name change, similar to method parameters.
Upvotes: 5
Reputation: 26682
As you are just changing the name for the generic type place holder, this should not be a problem. However, as a generic rule you shouldn't make things overly complex. If your generic class only has one genetic type then T is just as clear as TSomething. In fact, the use of T has become standard for generics.
But if the generic class uses two types then more descriptive names would be better. So,
public class Foo<T1, T2>
{
public T1 Bar(T2 something) { return ... }
}
Would be bad. You would rather have
public class Foo<TResult, TSource>
{
public TResult Bar(TSource something) { return ... }
}
But again, if there's just one type, stick to T. Changing the name won't matter as it's just a place holder.
Upvotes: 2
Reputation: 9814
Generics are resolved at compile time, to allow for compile time type checks. Indeed allowing those checks to still take place is what they are there for.
While I have no information either way, I do not see how this would break anything.
Source Compability is maintained.
And binary compatibility should only care what is put there instead of the T/TMoreDescriptive/type placeholder.
It is worth pointing out that .NET is very specific about wich .dll it loads. When .NET was made, we had at least a decade of experience that just using the dll name causes issues with versioning. So .,NET uses the DLL's name, the version and a public token (think GUID) to make certain it really is the exact DLL the compiler worked against. So if you want to make a major change, you can just make sure you get another public token and it should work out.
Upvotes: 2