代码之家  ›  专栏  ›  技术社区  ›  Wim Coenen

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

c#
  •  8
  • Wim Coenen  · 技术社区  · 15 年前

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

    VisualStudio将自动显示此时的正确错误(在生成代码之前)。现在插入“I”将“Foo”变成“IFoo”,然后 . 错误的“显式转换存在”版本现在将自动出现在错误输出窗口和分配错误的工具提示中。

    那么错误的错误 当您显式地按F6生成时,将再次消失 .

    6 回复  |  直到 15 年前
        1
  •  10
  •   Eric Lippert    15 年前

    我无法再现所报道的行为。如果它真的繁殖,那就是一个错误。没有从字符串到任何用户定义接口的显式转换。

    请用你正在使用的编译器的版本号和一个小程序来更新这个问题,我会把一个bug输入bug数据库。

    谢谢!

    更新:显然它没有在命令行上复制,但据称是在VS2008中复制的。

    我无法在VS2010的RC构建中复制它,所以如果这实际上是VS2008中的一个bug,那么它可能已经被修复了。不幸的是,我现在还没有安装VS2008的测试工具。

    不管怎样,如果你看到了这个诊断,那么很有可能它只是语义分析器中错误报告启发式中的一个bug。显然,从string到IFoo没有显式的转换。

    未密封 类型转换为任何接口类型,因为可能存在实现该接口的派生类型。但是字符串是密封的,所以错误应该是“no conversion”。

        2
  •  5
  •   p.campbell    6 年前

    我复制了这种行为。 Reproduced.

    Microsoft Visual Studio 2008

    版本9.0.30729.1 SP

    Microsoft.NET框架

    版本3.5 SP1

        3
  •  1
  •   Kevin Crowell    15 年前

    无耻地从 MSDN - Compiler Error CS0266 MSDN - explicit (C# Reference) .

    如果有代码试图转换两个无法隐式转换的类型,例如在将基类型赋值给缺少显式转换的派生类型时,就会发生此错误。

    这个 明确的

    // 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;
    
        4
  •  0
  •   Anton Gogolev    15 年前

    无法复制。 CS0029 只有

    CS0266 然而,他说

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

        5
  •  0
  •   codymanix    15 年前

    如果您编写了以下内容,则会发生此错误:

    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
    }
    
        6
  •  0
  •   Chris    15 年前

    是的,没有明确的方法在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";
            }
        } 
    }