C#使用别名作为其他使用别名的类型参数

问题描述 投票:4回答:5

我试图在我的C#程序的顶部定义一对类型别名。这是我正在尝试做的一个简短示例:

using System;
using System.Collections.Generic;

namespace Foo {
    using TsvEntry = Dictionary<string, string>;
    using Tsv = List<TsvEntry>;
}

当我尝试使用mcs 3.2.8.0编译它时,我收到以下错误消息:

foo.cs(6,19): error CS0246: The type or namespace name `TsvEntry' could not be found. Are you missing an assembly reference?

是否有可能在C#中的其他别名中使用using别名,或者我错过了关于using语句的工作方式?

c# alias directive using
5个回答
5
投票

检查此问题的文档:

https://msdn.microsoft.com/en-us/library/aa664765(v=vs.71).aspx

它说:

写入using-alias-directives的顺序没有意义,using-alias-directive引用的namespace-or-type-name的解析不受using-alias-directive本身或其他使用的影响 - 立即包含编译单元或命名空间体中的指令。换句话说,using-alias-directive的namespace-or-type-name被解析为好像直接包含编译单元或命名空间体没有using-directives。在示例中

namespace N1.N2 {}
namespace N3
{
   using R1 = N1;         // OK
   using R2 = N1.N2;      // OK
   using R3 = R1.N2;      // Error, R1 unknown
}

最后一个using-alias-directive导致编译时错误,因为它不受第一个using-alias-directive的影响。

从技术上讲,您不能使用相同的命名空间,但如果您在命名空间1中执行别名,并在嵌套命名空间中为此别名执行别名,则它将起作用:

namespace N1
{
    namespace N12 { }
}

namespace N2
{
    using R1 = N1;

    namespace N2
    {
        using R2 = R1.N12;
    }
}

我不确定在您的具体示例中使用别名是否值得,考虑尽可能少地使用它们,主要用于解决命名空间冲突。


3
投票

来自MSDN's Using alias directives

写入using-alias-directives的顺序没有意义,using-alias-directive引用的namespace-or-type-name的解析不受using-alias-directive本身或其他使用的影响 - 立即包含编译单元或命名空间体中的指令。换句话说,using-alias-directive的namespace-or-type-name被解析为好像直接包含编译单元或命名空间体没有using-directives。

//强调我的

在您的示例中,最后一个using-alias-directive导致编译时错误,因为它不受第一个using-alias-directive的影响。


2
投票

正如其他答案的补充一样。

如果你真的想继续你的方式,嵌套命名空间将是你要走的路。因为对于第二个命名空间,然后将定义第一个使用。

由于您处于更深的命名空间,因此以下方法可行:

namespace N1
{
    using TsvEntry = Dictionary<string, string>;

    namespace N1.N2
    {
        using Tsv = List<TsvEntry>;

    }
}

请注意,虽然它工作正常,但我不建议使用这种代码结构,因为您最终可能会使用深层嵌套代码。


1
投票

正如其他人所提到的,使用Alias这种方式是不可能的,但是,您可以使用类继承获得类似的功能。

使用您的示例,您可以执行以下操作:

using System;
using System.Collections.Generic;

namespace Foo {
    class TsvEntry : Dictionary<string, string> {}
    class Tsv : List<TsvEntry> {}
}

这具有额外的优势,您可以根据需要轻松地为这些类添加额外的功能。


1
投票

(在此处添加此内容是因为我在搜索相关问题时遇到了很多问题,因此可能对其他人有帮助)

如果您希望使用别名来实现函数式编程,那么您需要的是delegate关键字。你可以把delegate想象成一个接口,除了它是一个函数。

所以,而不是 using Expression = Func<string>; using Converter = Func<List<string>, Expression>; 你做 delegate string Expression(); delegate Expression Converter(List<string> tokenizedExpressions);

https://weblogs.asp.net/dixin/functional-csharp-function-type-and-delegate

© www.soinside.com 2019 - 2024. All rights reserved.