【问题标题】:C# using alias as type parameter in other using aliasC# 在其他使用别名中使用别名作为类型参数
【发布时间】:2016-06-25 14:40:03
【问题描述】:

我试图在我的 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


    【解决方案1】:

    检查此问题的文档:

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

    上面写着:

    using-alias-directives 的编写顺序没有 所引用的命名空间或类型名称的意义和解析 using-alias-directive 不受影响 using-alias-directive 本身或通过中的其他 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;
        }
    }
    

    我不确定在您的具体示例中是否值得使用别名,尽量少用它们,主要是为了解决命名空间冲突。

    【讨论】:

      【解决方案2】:

      来自MSDN's Using alias directives

      using-alias-directives 的编写顺序没有 所引用的命名空间或类型名称的意义和解析 通过 using-alias-directive 不受 using-alias-directive 本身或通过其他 using-directives 在 立即包含编译单元或命名空间主体。其他 换句话说,using-alias-directive 的命名空间或类型名称是 就像立即包含的编译单元一样解析或 命名空间主体没有使用指令。

      // 强调我的

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

      【讨论】:

        【解决方案3】:

        作为对其他答案的补充。

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

        由于您处于更深的命名空间中,因此以下内容将起作用:

        namespace N1
        {
            using TsvEntry = Dictionary<string, string>;
        
            namespace N1.N2
            {
                using Tsv = List<TsvEntry>;
        
            }
        }
        

        请注意,虽然它可以工作,但我不建议使用这种代码结构,因为您最终会得到深度嵌套的代码。

        【讨论】:

          【解决方案4】:

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

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

          using System;
          using System.Collections.Generic;
          
          namespace Foo {
              class TsvEntry : Dictionary<string, string> {}
              class Tsv : List<TsvEntry> {}
          }
          

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

          【讨论】:

            【解决方案5】:

            (在这里添加这个是因为我在搜索相关问题时经常遇到这个问题,所以它可能对其他人有帮助)

            如果您希望将别名用于函数式编程风格,您正在寻找的是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

            【讨论】:

              【解决方案6】:

              我同意避免添加嵌套命名空间以允许重用别名的建议。但是请注意,您可以免费获得一层嵌套。在您自己的命名空间之外定义您的基本别名。重用基本别名来为命名空间中的复合类型定义别名。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2018-01-04
                • 2021-05-28
                • 1970-01-01
                • 2016-06-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多