根据未引用的命名空间中定义的类型键入推断

时间:2014-12-05 13:37:35

标签: c# namespaces type-inference

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

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();

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

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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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 Console的{​​{1}}和一些反射功能,而编译器在编译时不知道它,因为您有{{1引用你的项目。