考虑以下工作代码:
RadComboBox rcb = new RadComboBox(); // Telerik.Web.UI.RadComboBox
rcb.Items.Add(new RadComboBoxItem("One", "1"));
rcb.Items.Add(new RadComboBoxItem("Two", "2"));
rcb.Items.Add(new RadComboBoxItem("Three", "3"));
// check all items
foreach (RadComboBoxItem i in rcb.Items)
{
i.Checked = true;
}
Run Code Online (Sandbox Code Playgroud)
如果我用var替换foreach循环,它将无法编译:
RadComboBox rcb = new RadComboBox(); // Telerik.Web.UI.RadComboBox
rcb.Items.Add(new RadComboBoxItem("One", "1"));
rcb.Items.Add(new RadComboBoxItem("Two", "2"));
rcb.Items.Add(new RadComboBoxItem("Three", "3"));
// check all items
foreach (var i in rcb.Items)
{
i.Checked = true;
}
Run Code Online (Sandbox Code Playgroud)
错误是:
“对象”不包含“已检查”的定义,也找不到找不到接受“对象”类型的第一个参数的扩展方法“已检查”(您是否缺少using指令或程序集引用?)
所以,我想知道,什么时候不能使用var?
编辑:只是为了澄清,我不是简单地问“为什么这行不通”?这是一个使问题更明显的示例:
List<Object> stuff = new List<object>();
stuff.Add("one");
stuff.Add("two");
stuff.Add("three");
foreach (string s in stuff)
{
if (s.Length > 3)
// do something
}
Run Code Online (Sandbox Code Playgroud)
现在,如果将东西中的字符串s更改为东西中的var,则显然不会进行编译。您不能只是随意地用var替换任何类型并期望它可以编译。我首先想到的问题就是我认为,由于rcb.Items的类型为RadComboBoxItemCollection,因此可枚举的类型为RadComboBoxItem,而事实并非如此。
不幸的是,我的示例通过将一些答案引向“为什么用var替换类型不起作用?”困扰了这个问题。路径。Paulo实际上回答了我所寻找的内容(其他人也做了部分回答),这就是为什么我给它最好的答案。
您可以var随时使用隐式键入。也就是说,何时可以从声明中派生类型。在这种情况下,似乎的实际类型Items是的集合object。这样var在声明中就知道了。
通过RadComboBoxItem在本质上执行与此非常相似的操作时显式声明该类型(但要进行更多的编译时检查):
foreach (var i in rcb.Items)
{
(i as RadComboBoxItem).Checked = true;
}
Run Code Online (Sandbox Code Playgroud)
可以将中的object实例Items隐式转换为RadComboBoxItem,但var不知道这样做。您必须明确地做到这一点。(就我个人而言,我会认为它的设计很奇怪RadComboBox,但这可能是早期设计决策的后遗症。.NET中的集合并不总是像今天这样具有很强的类型。ArrayList类似的东西曾经引起类似的问题。)