C# 无法将类型“X”隐式转换为“字符串”-何时以及如何决定它“不能”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/751303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:45:34  来源:igfitidea点击:

Cannot implicitly convert type 'X' to 'string' - when and how it decides that it "cannot"?

c#type-conversiontostring

提问by User

Right now I'm having it with Guids.

现在我正在使用Guids。

I certainly remember that throughout the code in some places this implicit conversion works, in others it does not. Until now I fail to see the pattern.

我当然记得在整个代码中,这种隐式转换在某些地方有效,而在其他地方则无效。直到现在我都看不到这种模式。

How the compiler decides when it cannot? I mean, the type method Guid.ToString()is present, isn't it called whenever this transformation is needed?

编译器如何决定何时不能?我的意思是,type 方法Guid.ToString()是存在的,它不是在需要这种转换时调用吗?

Can someone please tell me under what circumstances this transformation is done automatically and when I have to call myInstance.ToString()explicitly?

有人可以告诉我在什么情况下这种转换是自动完成的,什么时候我必须myInstance.ToString()明确调用?

采纳答案by Marc Gravell

In short, when there is an implicit or explicit conversion operator defined:

简而言之,当定义了隐式或显式转换运算符时:

class WithImplicit {
    public static implicit operator string(WithImplicit x) {
        return x.ToString();}
}
class WithExplicit {
    public static explicit operator string(WithExplicit x) {
        return x.ToString(); }
}
class WithNone { }

class Program {
    static void Main() {
        var imp = new WithImplicit();
        var exp = new WithExplicit();
        var none = new WithNone();
        string s1 = imp;
        string s2 = (string)exp;
        string s3 = none.ToString();
    } 
}

回答by Lucero

The only place where you effectively don't need to call ToString() yourself is when concatenating strings.

您实际上不需要自己调用 ToString() 的唯一地方是连接字符串时。

Guid g;
int i;
string s = "Hello "+g+' '+i;

Then there are some situations where the call is made by the .NET Framework, such as in String.Format().

然后在某些情况下调用是由 .NET Framework 进行的,例如在String.Format() 中

Other than that, the compiler will only convert a type if it is known to be compatible (e.g. base class or implementing an interface or via an explicitly coded conversion operator). When you use a cast and the compiler knows that the types cannot be compatible (e.g. not in the same inheritance line, and not interfaces), it will also say that it cannot convert it. The same goes for generic type parameters.

除此之外,编译器只会转换已知兼容的类型(例如基类或实现接口或通过显式编码的转换运算符)。当您使用强制转换并且编译器知道类型不兼容(例如,不在同一继承行中,而不是在接口中)时,它也会说它无法转换它。泛型类型参数也是如此。

回答by Guffa

No, there is no implicit conversion from GUIDto String, so that doesn't work anywhere at all in the code.

不,没有从GUIDto 的隐式转换String,因此在代码中的任何地方都不起作用。

It only works where there is an explicit conversion, but the conversion might not be very visible. For example when you concatenate strings:

它仅适用于存在显式转换的情况,但转换可能不是很明显。例如,当您连接字符串时:

string id = "--" + guidValue + " : " + num;

This may look like an implicit conversion from GUIDto String, but it isn't. The code that is generated actually looks like this:

这可能看起来像是从GUIDto的隐式转换String,但事实并非如此。生成的代码实际上是这样的:

string id = String.Concat(new object[] { "--", guidValue, " : ", num });

All operands are cast to the type Objectand placed in an array. The String.Concatmethod then calls the ToStringmethod for each item in the array to get the string representation for them.

所有操作数都被强制转换为该类型Object并放置在一个数组中。在String.Concat随后的方法调用ToString数组中的每个项目获得的字符串表示他们的方法。