var
只是“让编译器为我选择正确的变量类型”的简写(编译时类型推断是更精确的术语)。
另一方面,object
是一个特定的类型;所有其他引用类型都派生自 object
,因此您可以将任何内容分配给类型为 object
的变量。
var
是当你在问自己,我真的必须要两次输入那么长的类型名称吗?比如:
Dictionary<string, Func<List<Func<int, int, double>>, IEnumerable<Tuple<double, string>>>> myDict = new Dictionary<string, Func<List<Func<int, int, double>>, IEnumerable<Tuple<double, string>>>>();
朋友,你其实不需要这样做。使用var
代替即可:
var myDict = new Dictionary<string, Func<List<Func<int, int, double>>, IEnumerable<Tuple<double, string>>>>();
现在,myDict
真的是一个 Dictionary<string, Func<List<Func<int, int, double>>, IEnumerable<Tuple<double, string>>>>
,所以你可以向其中添加元素、枚举它等等。
如果你将它声明为 object
,你就不能对它进行任何由 Dictionary
提供的操作,只能执行所有对象都有效的操作。
变量仍然是强类型的,但使用对象时,您将不得不对所有内容进行转换。
var foo = "Hello, I am a string!";
// foo is a string, so this compiles
var fooCharArray = foo.ToCharArray();
object bar = foo;
// bar is not a string, so this does not compile
var barCharArray = bar.ToCharArray();
foo
是一个字符串,所以我们可以在foo
上调用字符串方法。foo
“向上转换”为一个对象。现在编译器不知道(因为它不应该知道!)bar
实际上是一个字符串,因此我们不能在bar
上调用字符串方法。编译器不允许从对象(或任何基础类型)到派生类型(如System.String
)的隐式向下转换。这是编译时类型安全规则的一部分。