Share via


C# Design-Time Breaking Changes

 


Short Description Delegate Co and Contra variance effect binding
Affected APIs None Severity Low Compat Switch Available No

 


Description The addition of delegate co and contra variance results in this case binding to a different method than it did in previous versions

 


User Scenario  delegate void D(string s);

class A {
   public void M(string s) { }
}

class B : A {
   public void M(object o) { }

   static void Main() {
      B b = new B();
      D d = new D(b.M); // used to bind to A.M, now binds to B.M
   }
}

 


Work Around Modify code

 


 

 


Short Description Protected constructors can no longer be called
Affected APIs None Severity Low Compat Switch Available No

 


Description It used to be possible to create an instance of an object with a protected constructor from inside a derived class. This was a security issue, so it is no longer possible to do this. It is still possible to call a protected constructor though a base constructor call.

 


User Scenario  class B {
   protected B() {}
}

class D : B {
   D() : base () {} // this still works
   static void Main() {
      new B(); // this breaks
   }
}

 


Work Around None

 


 

 


Short Description Conditional Grammar ambiguity
Affected APIs none Severity Low Compat Switch Available No

 


Description Because of the new nullable syntax, there are certain scenarios where the compiler cannot tell the difference between a conditional operator and the nullable ? syntax.

 


User Scenario  class C {
   int F() {}
   int G () {}

   static void Main() {
      bool A;
      for (A ? F() : G(); ; ) // breaking - will report an error
   }
}

 


Work Around Modify code

 


 

 


Short Description Ambiguity between comparison and generic definition
Affected APIs None Severity Low Compat Switch Available No

 


Description The addition of generics has led to an ambiguity between a generic method and function parameters.

 


User Scenario  class C {
   static void F(bool a, bool b) { }

   static void Main() {
      int a, b, c;

      F(a < b, c > (7)); // now an error
   }
}

 


Work Around Modify code. For a comparison, this can be done by adding parentheses. A generic method call would need to be written as two separate operations.

 


 

 


Short Description Redefinition of Dispose() no longer allowed
Affected APIs None Severity Low Compat Switch Available No

 


Description The user could define Dispose() methods that could interfere with the proper operation of disposable classes

 


User Scenario  class C : IDisposable {
   void IDisposable.Dispose() {}
   public void Dispose {
      // do something different than IDisposable.Dispose
   }
   static void Main() {
      using (C c = new C()) {
         // C.Dispose not C.IDisposable.Dispose now called
      }
   }
}

 


Work Around Remove or rename the methods.

 


 

 


Short Description cscompmgd.dll is now obsolete
Affected APIs APIs in cscompmgd.dll Severity Low Compat Switch Available No

 


Description Some users used undocumented interfaces in this DLL to compile code. This was only intended for internal use.

 


User Scenario compiling C# code with cscompmdgd.dll

 


Work Around use Microsoft.CSharp.Compiler instead

 


 

 


Short Description /incremental flag generates warning
Affected APIs None Severity Low Compat Switch Available No

 


Description The C# compiler used to provide the capability to compile incrementally. This has been removed to improve compiler robustness

 


User Scenario Using /incremental on the command line

 


Work Around Remove the command-line option

 


 

 


Short Description Referencing two types with the same name from different dlls generates error
Affected APIs None Severity Low Compat Switch Available No

 


Description In previous versions, the C# compiler would choose one type in this situation. It will now report an error.

 


User Scenario See title

 


Work Around Use extern namespace aliases

 


 

 


Short Description Compat: Migrating an RTM project containing an "invoke" doesn't compile in v2.0
Affected APIs None Severity Low Compat Switch Available No

 


Description We erroneously broke a previous scenario with Invoke across assmebly. We reverted the change.

 


User Scenario See title

 


Work Around No need as there is no breaking change.

 


 

 


Short Description params on an explicit impl shouldn't be allowed unless it's also on the interface method.
Affected APIs None Severity Low Compat Switch Available No

 


Description If an interface method doesn't have params then the explicit interface implementation shouldn't be allowed to have it either.

 


User Scenario  interface I {
      void F1(params int[] a);
      void F2(params int[] a);
      void F3(int[] a);
}

class C : I {
      void I.F1(params int[] a) { }
      void I.F2(int[] a) { }
      void I.F3(params int[] a) { }
}

 


Work Around Add the params keyword

 


 

 


Short Description Changes to the way we convert to/from booleans in JScript result in more ambiguities in resolving multi-argument methods.
Affected APIs none Severity Medium Compat Switch Available No

 


Description Changes to the way we convert to/from booleans in JScript result in more ambiguities in resolving multi-argument methods. For example if both overloads of a method expect a parameter of type int, but a boolean is passed we may error now where we would have been able to choose a funtion before.

 


User Scenario        class Alpha17_5
      {
         public var value = "none";
         public function Alpha17_5 (x: int, y: Number) { value = "one"; }
         public function Alpha17_5 (x: double, y: String) { value = "two"; }
      }

      var alpha17_5_1: Alpha17_5 = new Alpha17_5(true, "hello"); //This used to compile but now gives an error
//error JS1184: More then one constructor matches this argument list

 


Work Around Write an additional function to handle booleans or call the existing functions with a non-boolean.

 


 

 


Short Description Referencing multiple assemblies with the same type gives compiler error
Affected APIs none Severity Medium Compat Switch Available No

 


Description In V1.1 the compiler was relaxed in giving errors when referencing multiple assemblies possibly containing the same type. It wouldn't give any error and it would pick one of the imported type. In V2.0 we fixed the problem so that now the user is notified if he/she is erroneously referencing the same assembly twice.

 


User Scenario The user erroneously reference two assemblies with the same type in each of them.

 


Work Around Remove one reference

 


 

 


Short Description Having a field with the same name as an internal class doesn't compile
Affected APIs none Severity Medium Compat Switch Available No

 


Description In V2.0, having a field with the same name as an internal class doesn't compile. None of the Microsoft compilers can compile such code. You can create it with reflection. We used to compile in V1.1 when referencing such an assembly. Now we give the correct error message: client.cs(7,30): error CS0229: Ambiguity between 'A.Fields' and 'A.Fields'

 


User Scenario The user writes reflection code that erroneusly create the situation.

 


Work Around Do not generate this ambiguous situation

 


 

 


Short Description Sealing a property with just the getter (or setter) seals both of them in V2.0
Affected APIs none Severity Medium Compat Switch Available No

 


Description In V1.1 if you seal a property with just the accessor you would just seal the accessor. In version 2.0 you seal both the accessor and the setter

 


User Scenario Any code which expected a accessor to affect just the accessor

 


Work Around

 

 

 

 

If your original intention was to seal just the getter/setter:

  1. In code forward to a separate method that can then be virtual as in:
    ...
    public sealed int Value {
       get {
          return GetValue();
       }
    }
    protected virtual int GetValue() { return 3;}
  2. Move your property getter/setter to a method
  3. Unseal the property

 


 

 


Short Description In V1.1 the compiler would allow an explicit implementer to add the params modifier. In V2.0 we report an error
Affected APIs none Severity Medium Compat Switch Available No

 


Description In V1.1 the compiler would allow an explicit implementer to add the params modifier. In V2.0 we report an error at compilation time. This will only impact recompilation scenarios (source compatibility)

 


User Scenario The code example demonstrates an exemplar scenario

 


Work Around Remove the params from the explicit implementation.