gpt4 book ai didi

c# - foreach 如何将对象转换为指定类型?

转载 作者:太空狗 更新时间:2023-10-30 00:05:18 25 4
gpt4 key购买 nike

我对 C# 中的 foreach 行为有疑问。

我的自定义类实现自定义 GetEnumerator。此方法返回另一个可隐式转换为 stringobject

但是,如果我执行 foreach(customClass 中的 string s),它会在运行时失败(“无法将 .. 类型的对象转换为字符串”)。

但是,如果我执行 string x = new B(),它就像一个魅力。

注意:这里没有什么特别需要实现的,我只是想了解发生了什么。我对这种-通用行为特别感兴趣。

有什么想法吗?我缺少哪些基础知识?

复制这个的代码:

public class A : IEnumerable
{
#region IEnumerable Members

public IEnumerator GetEnumerator()
{
yield return new B();
}

#endregion
}

public class B
{
public static implicit operator string( B b )
{
return "to-stringed implicit";
}
}

// CODE:

A a = new A();

// Works.
B b = new B();
string xxx = b;

// Doesnt work.
foreach( string str in a )
{
}

最佳答案

您的隐式转换只能在编译器认为它可以在编译时使用时使用:

B b = new B();
string str = b;

它不能在运行时使用:

B b = new B();
object obj = b;
string str = obj; // will fail at run-time

基本上,这是因为查看所有 obj 的可能转换成本太高了到 string那可能有用。 (参见 this Eric Lippert blog post)。


你的 IEnumerator返回对象,所以调用 foreach (string str in a)正在尝试转换 objectB在运行时。

var e = a.GetEnumerator();
e.MoveNext();
object o = e.Current;
string str = o; // will fail at run-time

如果您改为使用 foreach(B item in a) { string str = item; ... } ,运行时转换来自 objectB (有效,因为每个对象一个 B ),以及从 B 的转换至 str可以由编译器生成。

var e = a.GetEnumerator();
e.MoveNext();
object o = e.Current;
B item = o; // will work at run-time because o _is_ a B
string str = item; // conversion made by the compiler

解决这个问题的另一种方法是制作 A实现 IEnumerable<B>而不仅仅是 IEnumerable .然后,foreach (string str in a)多译为

var e = a.GetEnumerator();
e.MoveNext();
B b = e.Current; // not object!
string str = b; // conversion made by the compiler

因此编译器可以进行转换而无需更改 foreach循环。

关于c# - foreach 如何将对象转换为指定类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14630700/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com