簡體   English   中英

當C#編譯器打印“存在顯式轉換”時,它意味着什么?

[英]What does the C# compiler mean when it prints “an explicit conversion exists”?

如果我做一個空的測試類:

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進行構建時 ,錯誤的錯誤會再次消失

我無法重現報告的行為。 如果它確實重現,那就是一個bug。 沒有從字符串到任何用戶定義的接口的顯式轉換。

請使用您正在使用的編譯器的版本號以及重現問題的小程序更新問題,我將在bug數據庫中輸入錯誤。

謝謝!

更新:顯然它不會在命令行上重現,但據稱在VS2008中重現。

我無法在VS2010的RC版本中重現它,所以如果這實際上是VS2008中的一個錯誤,它可能已被修復。 我現在還沒有安裝VS2008方便測試。

無論如何,如果你看到那個診斷,那么幾率非常好,它只是語義分析器中錯誤報告啟發式的一個錯誤。 顯然,沒有從字符串到IFoo的顯式轉換。

存在從任何未密封類型到任何接口類型的顯式轉換,因為可能存在實現接口的派生類型。 但字符串是密封的,因此錯誤應該只是“無轉換”。

我已經復制了這種行為。 轉載。

Microsoft Visual Studio 2008

版本9.0.30729.1 SP

Microsoft .NET Framework

版本3.5 SP1

已安裝版:專業版

無恥地從MSDN中刪除 - 編譯器錯誤CS0266MSDN - 顯式(C#參考)

如果您的代碼嘗試轉換無法隱式轉換的兩種類型,例如在將基類型分配給缺少顯式轉換的派生類型時,則會發生此錯誤。

explicit關鍵字聲明了必須使用強制轉換調用的用戶定義的類型轉換運算符。 例如,此運算符從名為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;

無法重現這一點。 CS0029只有

無法將類型'type'隱式轉換為'type'“

但是, CS0266

無法將類型'type1'隱式轉換為'type2'。 存在顯式轉換(您是否錯過了演員?)

但是,由於Foo是一個空的類/接口,這是不可能的,IMO。

如果你寫了這個錯誤會發生:

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
}

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM