【问题标题】:Type inference against type defined in unreferenced namespace针对未引用命名空间中定义的类型进行类型推断
【发布时间】:2014-12-05 13:37:35
【问题描述】:

给定一个类和命名空间定义如下;

namespace Models
{
    public class Foo
    { 
    }
}

还有以下……

namespace Factories
{
    using Models;

    class FooFactory
    {
        public Foo GetFoo()
        {
            return new Foo();
        }
    }
}

最后……

namespace InferenceTest
{
    using Factories;

    class Program
    {
        static void Main()
        {
            Foo foo = new FooFactory().GetFoo();
        }
    }
}

如您所料,此代码无法编译并出现错误“找不到类型或命名空间名称 'Foo'(您是否缺少 using 指令或程序集引用?)”

但是,如果我将这一行改为这个......

var foo = new FooFactory().GetFoo();

然后它编译并运行得很好。

为什么会有这种差异?什么是类型推断允许它查看名称空间中尚未导入的类型。命名空间只是语法糖吗?

【问题讨论】:

  • 我不太了解这一点,无法发布权威答案,但是我会说,当您使用 var 时,您将其留给编译器来确定类型,因此拥有合格的命名空间会没有帮助,因为它知道类型是什么。当您使用显式类型时,您可能会引用具有相同名称(不同命名空间)的不同类型,因此您必须明确说明如何限定类型。
  • 您不必使用 using 指令来声明该类型的变量,它只允许您使用缩短的类型声明。 Models.Foo foo = new FooFactory().GetFoo(); 可以编译得很好。使用 var 时,使用什么指令并不重要,因为您不是在说“声明这种特定类型的变量 foo”,而是在说“声明变量 foo 并从初始化中推断类型”。
  • 哦,好的,所以“var”实际上只是被完全限定的类型名称替换了..“Models.Foo”?
  • 我不是编译器专家,但我的直觉说它不会被任何东西取代,类型声明告诉编译器变量是什么类型,var 只是告诉编译器推断类型。跨度>
  • 公平 - 有道理,谢谢。

标签: c# namespaces type-inference


【解决方案1】:

var foo = new FooFactory().GetFoo(); 编译的原因很简单。编译器推断 foo 不仅是 Foo 是 Models.Foo 类型。
同推Models.Foo foo2 = new FooFactory().GetFoo();.
注意Foo foo2 = new FooFactory().GetFoo(); 是不同的。

【讨论】:

    【解决方案2】:

    namespaces that have not been imported是你无效的理由;您不导入名称空间,而是将它们用作本地名称。编译中发生的唯一导入是引用程序集,即使它不是真正的导入,只是导入了一些元数据。 (例如版本和 GUID)

    这意味着当您引用诸如System.dll 之类的程序集时,您可以使用其中的所有类;为了向您展示它的含义,我将给您这个反射示例:

    internal class Program {
        private static void Main( ) {
            System.Type.GetType("System.Console")
                .GetMethod("WriteLine",new[] {System.Type.GetType("System.String")})
                .Invoke(null,new object[]{"Hello World"});
        }
    }
    

    您没有“导入”任何命名空间,但仍然使用了 string ConsoleWriteLine 和一些反射功能,而编译器在编译时并不知道它,因为您的项目引用了 System.dll

    【讨论】:

      猜你喜欢
      • 2022-12-03
      • 2016-04-23
      • 2017-06-06
      • 2015-12-12
      • 1970-01-01
      • 2022-11-07
      • 2013-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多