- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对 C#
中的 foreach
行为有疑问。
我的自定义类实现自定义 GetEnumerator
。此方法返回另一个可隐式转换为 string
的 object
。
但是,如果我执行 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)
正在尝试转换 object
到 B
在运行时。
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; ... }
,运行时转换来自 object
至 B
(有效,因为每个对象是一个 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/
我是一名优秀的程序员,十分优秀!