开发者

What does the C# compiler mean when it prints "an explicit conversion exists"?

If I make an empty test class:

public class Foo
{
}

And I try to compile code with this statement:

Foo foo = "test";

Then I get this error as expected:

Cannot implicitly convert type 'string' to 'ConsoleApplication1.Foo'

However, if I change the declaration of Foo from class to interface, the error changes to this (emphasis mine):

Cannot implicitly convert type 'string' to 'ConsoleApplication1.Foo'. An explicit conversion exists (are you missing a cast?)

What is this "explicit conversion" which is supposed to exist?

update: the issue is a bit more subtle than I initially thought. To reproduce it, put this code in a new console application in Visual Studio 2008:

namespace ConsoleApplication1
{
    class Foo
    {
    }

    int开发者_C百科erface IFoo
    {
    }


   class Program
   {
      static void Main(string[] args)
      {
         Foo b = "hello";
      }
   }
}

Visual studio will automatically show the correct error at this point (before you build the code). Now insert the "I" to turn "Foo" into "IFoo" and wait a few seconds without building. The "explicit conversion exists" version of the error will now appear automatically in the error output window and in the tool tip for the assignment error.

The erroneous error then disappears again when you explicitly hit F6 to build.


I am unable to reproduce the reported behaviour. If it does in fact reproduce, that's a bug. There is no explicit conversion from string to any user-defined interface.

Please update the question with the version number of the compiler you're using and a small program that reproduces the problem, and I'll get a bug entered into the bug database.

Thanks!

UPDATE: Apparently it does not reproduce on the command line, but is alleged to reproduce in VS2008.

I am unable to reproduce it in the RC build of VS2010, so if this was in fact a bug in VS2008, it's probably been fixed. I don't have an installation of VS2008 handy right now to test unfortunately.

Regardless, if you're seeing that diagnostic then odds are very good it is simply a bug in the error reporting heuristics in the semantic analyzer. Clearly there is no explicit conversion from string to IFoo.

There is an explicit conversion from any unsealed type to any interface type because there could be a derived type which implements the interface. But string is sealed, so the error should simply be "no conversion".


I have reproduced this behaviour.

What does the C# compiler mean when it prints "an explicit conversion exists"?

Microsoft Visual Studio 2008

Version 9.0.30729.1 SP

Microsoft .NET Framework

Version 3.5 SP1

Installed Edition: Professional


Shamelessly ripped from MSDN - Compiler Error CS0266 and MSDN - explicit (C# Reference).

This error occurs if you have code that attempts to convert two types that cannot be implicitly converted, such as in an assignment of a base type to a derived type that is missing an explicit cast.

The explicit keyword declares a user-defined type conversion operator that must be invoked with a cast. For example, this operator converts from a class called Fahrenheit to a class called Celsius:

// Must be defined inside a class called Farenheit:
public static explicit operator Celsius(Farenheit f)
{
    return new Celsius((5.0f/9.0f)*(f.degrees-32));
}

This conversion operator can be invoked like this:

Farenheit f = new Farenheit(100.0f);
Celsius c = (Celsius)f;


Cannot reproduce this. CS0029 has only

Cannot implicitly convert type 'type' to 'type'"

CS0266 , however, says

Cannot implicitly convert type 'type1' to 'type2'. An explicit conversion exists (are you missing a cast?)

but with Foo being an empty class/interface this is not possible, IMO.


This Error would occur if you had written:

class Foo:IFoo
{
}

interface IFoo
{
}

static void Main(string[] args)
{
    IFoo i = new Foo();
    Foo f = i; // here this message would occur, since IFoo *can* Convert to Foo (Since Foo implements IFoo), but it must be casted explicitly
}


Yes, there is no explicit way to convert between Foo and string. However, if you'd like to use that syntax, Foo foo = "Hello World" as shorthand you can. It's accomplished by using the implicit operator, as defined here.

It allows you to perform these type of conversions implicitly (hence the name).

To get that type of facade accomplished, here is how you do it:

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

namespace ImplicitOperatorTest
{
    class Foo
    {
        private string foo;

        public Foo(string foo)
        {
            this.foo = foo;
        }

        public static implicit operator string(Foo foo)
        {
            return foo;
        }

        public static implicit operator Foo(string foo)
        {
            return new Foo(foo);
        }
    }

    interface IFoo
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
            Foo b = "hello";
        }
    } 
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜