c#有一个强类型
本文关键字:强类型 有一个 | 更新日期: 2023-09-27 18:03:08
链接:http://msdn.microsoft.com/en-us/library/bb383973.aspx
…隐式类型局部变量是强类型的,就像您自己声明了类型一样,但是编译器确定类型…
但是我有这样一段代码:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["user"] == null) Response.Redirect("Default.aspx");
StringBuilder sb = new StringBuilder();
foreach (var item in Session)
{
sb.Append("Session Parameter: [");
sb.Append(item);
sb.Append("]<p />Guid Value: [");
sb.Append(Session[item] + "]");
}
Response.Write(sb.ToString());
}
我在Visual Studio中得到这样的错误:
参数1:不能将'object'转换为'string'
sb.Append(Session[item] + "]");
但是item
在运行时被识别为string
类型,正如我在调试器中看到的。
当我在msdn/书中读到var
时,我认为var
与rtti无关。编译器只是在编译时将隐式类型的变量更改为显式类型,如string, int
等。
为什么我发现了这样的错误?
c#中的var
声明是强类型的,但在这种情况下,您正在处理值Session
中的非泛型集合类型。这将导致c#选择object
作为item
的类型,因此在需要string
的位置使用item
时会出现错误。
对于非泛型集合,您仍然需要在foreach
块中显式键入迭代器变量
foreach(string item in Session) {
...
}
"为什么会出现这样的错误?"-因为sb.Append(Session[item] + "]");
期待一个字符串-所以你需要将Session[item]
转换为字符串:
sb.Append(((string)Session[item]) + "]");
根据MSDN文章如何:从会话状态读取值。
在这种情况下,Session
是实现IEnumerable
的httpessionstate(尽管如果它实现IEnumerable<object>
也会发生相同的情况),因此您的var
被编译器映射为:
foreach (object item in Session)
{
在本例中,这可能是IEnumerable
,因此您需要在foreach
中显式指定类型:
foreach (string item in Session)
{
对于非泛型IEnumerable
集合,foreach
允许这样做。
关于你的主要问题:
c#中var有强类型吗?
是的。在本例中,集合本身不提供强类型,因此var
使用System.Object
。
你是正确的,var
是静态类型的(即在编译时)。然而,var
的静态类型来自上下文,这使得编译器可以派生var
的类型。
在Session
实现IEnumerable
的情况下,编译器可以派生的唯一类型是object
,从而导致您描述的错误。
如果实现了Session
,比如IEnumerable<string>
,那么循环中的var
将等同于string
,而不是object
。
在您的示例中,它归结为Session
是什么类型的集合。在本例中,它是一个对象集合,因此编译器将var item
变为object item
。
正如其他答案所指出的,Session的Item属性(它是默认的索引器)是object类型的。这就是为什么你从索引器获得一个对象——那是它的返回类型。
http://msdn.microsoft.com/en-us/library/k8s0kehy (v = vs.100) . aspx
这是因为对象是不同的类型。这很像为什么派生类不同于它的基类(例如:class D : B{}
)。所有的类类型继承Object
,值(结构)我相信没有。他们需要被封闭起来。Session
集合只是说它有一堆对象,任何东西都可以在那里。运行时不会尝试检查,除非您要求它(通过类型转换或其关键字)。
foreach中的var表示该变量(项)应该是会话枚举器返回的任何类型。在大多数情况下,指定不同的类型类似于类型转换。
仅仅因为某个东西是一个类或盒子(这意味着它是一个对象)并不意味着编译器知道这个对象实际上是什么。事实上,我认为标准建议,如果某些东西成为对象,编译器不应该自动转换它,即使它知道它实际上是什么类型(也许它知道从上面的几行)