当C#编译器打印“存在显式转换”时,它意味着什么?

时间:2010-03-26 16:09:28

标签: c#

如果我做一个空的测试课:

public class Foo
{
}

我尝试使用以下语句编译代码:

Foo foo = "test";

然后我按预期得到了这个错误:

  

无法将类型'string'隐式转换为'ConsoleApplication1.Foo'

但是,如果我将Foo的声明从类更改为接口,则错误会更改为此(强调我的):

  

无法隐式转换类型   'string'到'ConsoleApplication1.Foo'。   存在明确的转化(是吗?   错过演员?)

这应该存在的“显式转换”是什么?

更新:这个问题比我最初的想法更微妙。要重现它,请将此代码放在Visual Studio 2008中的新控制台应用程序中:

namespace ConsoleApplication1
{
    class Foo
    {
    }

    interface IFoo
    {
    }


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

Visual Studio将在此时自动显示正确的错误(在构建代码之前)。现在插入“I”将“Foo”变为“IFoo”,等待几秒钟而不构建。现在,“显式转换存在”版本的错误将自动出现在错误输出窗口和工具提示中,以便分配错误。

当您明确按F6构建时,错误的错误会再次消失。

6 个答案:

答案 0 :(得分:10)

我无法重现报告的行为。如果它确实重现,那就是一个bug。没有从字符串到任何用户定义的接口的显式转换。

请使用您正在使用的编译器的版本号以及重现问题的小程序更新问题,我将在错误数据库中输入错误。

谢谢!

更新:显然它不会在命令行上重现,但据称会在VS2008中重现。

我无法在VS2010的RC版本中重现它,所以如果这实际上是VS2008中的一个错误,它可能已被修复。我现在没有安装VS2008的方便,不幸的是。

无论如何,如果你看到那个诊断,那么几率非常好,它只是语义分析器中错误报告启发式的一个错误。显然,没有从字符串到IFoo的显式转换。

从任何未密封的类型到任何接口类型都有显式转换,因为可能存在实现接口的派生类型。但字符串是密封的,所以错误应该只是“没有转换”。

答案 1 :(得分:5)

我已经复制了这种行为。 Reproduced. http://i44.tinypic.com/fk6ss6.jpg

Microsoft Visual Studio 2008

版本9.0.30729.1 SP

Microsoft .NET Framework

版本3.5 SP1

已安装版:专业版

答案 2 :(得分:1)

MSDN - Compiler Error CS0266MSDN - explicit (C# Reference)无耻地撕掉。

如果您的代码尝试转换无法隐式转换的两种类型,例如将基类型分配给缺少显式转换的派生类型,则会发生此错误。

显式关键字声明了必须使用强制转换调用的用户定义的类型转换运算符。例如,此运算符从名为Fahrenheit的类转换为名为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));
}

可以像这样调用此转换运算符:

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

答案 3 :(得分:0)

无法重现这一点。 CS0029只有

  

无法将类型'type'隐式转换为'type'“

然而,

CS0266

  

无法将类型'type1'隐式转换为'type2'。存在显式转换(您是否错过了演员?)

但是Foo是一个空的类/接口,这是不可能的,IMO。

答案 4 :(得分:0)

如果您写了:

,就会发生此错误
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
}

答案 5 :(得分:0)

是的,没有明确的方法在Foo和string之间进行转换。但是,如果您想使用该语法,可以使用Foo foo = "Hello World"作为简写。它是通过使用此处定义的implicit运算符完成的。

它允许您隐式执行这些类型的转换(因此名称)。

要完成这种类型的外观,请按以下步骤操作:

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";
        }
    } 
}