Kevin Montrose
Kevin Montrose

Reputation: 22591

Is Changing A Generic Parameter's Name A Breaking Change

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

Answers (3)

Klaycon
Klaycon

Reputation: 11080

No, there is no such case.

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

Wim ten Brink
Wim ten Brink

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

Christopher
Christopher

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

Related Questions