views:

395

answers:

1

We have a type called Action in our library. We support VS2005, 2008 and now trying to support VS2010 too. When I include the namespace containing our 'Action' type and also 'System' together in a file and try to use it, it cribs saying ambiguous reference call between our Action type and System.Action delegate. This is happening only in VS2010 and it does not throw error in VS2008 or VS2005 even though nothing has changed with the Action delegate (namespace, assembly everything is the same between 3.5 and 4.0). Any idea why this could be happening?

UPDATE:

I created a simple application to reproduce this:

Class1.cs:

using System; using System.Collections.Generic; using System.Text;

namespace Namespace1 { public enum Action { Mouse, Keyboard } }

Class2.cs:

using Namespace1; using System; using System.Collections.Generic; using System.Text;

namespace Namespace2 { public class Class2 { public Class2() { Action a; } } }

The above code compiles fine in VS2008 but throws error in VS2010: "error CS0104: 'Action' is an ambiguous reference between 'Namespace1.Action' and 'System.Action'"

I get the same error when I use VS2010 and target Framework 3.5 instead of 4.0.

Thanks, Niranjan

A: 

The question that jumps to mind is why it isn't ambiguous in C#3 (I think this would be a language error).

And a quick test shows it is:

using System;
using ConsoleApplication1;

namespace ConsoleApplication1 {
    class Action { };
    class Program {
        static void Main(string[] args) {
            Action a = new Action();
        }
    }
}

class P2 {
    public void foo() {
        Action a;
    }
}

In VS2008 (C#3) get error: "'Action' is an ambiguous reference between 'System.Action' and 'ConsoleApplication1.Action'" in P2.foo().

There may be slight changes in lookup rules about how different cases (e.g. identifier in current namespace takes precedence (as in class Program above).

There are two options to disambiguate:

  1. Use fully qualified identifiers (in the above, either System.Action or ConsoleApplication1.Action.
  2. Use a namespace alias to fully qualify the identifier without so much typing:

    using MyAction = MyNamespace.Action;

NB. VS2010/C#4 (beta 2) gives the same result with the code above as VS2008/C#3.

Richard