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#有一个强类型

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表示该变量(项)应该是会话枚举器返回的任何类型。在大多数情况下,指定不同的类型类似于类型转换。

仅仅因为某个东西是一个类或盒子(这意味着它是一个对象)并不意味着编译器知道这个对象实际上是什么。事实上,我认为标准建议,如果某些东西成为对象,编译器不应该自动转换它,即使它知道它实际上是什么类型(也许它知道从上面的几行)

相关文章: