【问题标题】:Aliasing multiple classes in C#C#中多个类的别名
【发布时间】:2015-10-30 15:04:28
【问题描述】:

我想(正在尝试)使我的代码更具可读性。我一直在使用下面的类别名。

using Histogram = EmpiricScore<int>;
using FeatureHistogram = Dictionary<string, EmpiricScore<int>>;

但我认为类似(注意:我试图在这里用Histogram 来描述FeatureHistogram,而不是EmpiricScore&lt;int&gt;&gt;):

using Histogram = EmpiricScore<int>;
using FeatureHistogram = Dictionary<string, Histogram>;

似乎更具可读性(依赖关系可以更深入,如果我创建一个分层特征直方图会怎样),并且更容易重构(如果我碰巧认为直方图这个名字是不幸的)。但是编译器不会这样做。为什么 ?有什么办法可以规避?

创建新类似乎有点矫枉过正......

【问题讨论】:

  • @Micky Duncan。谢谢,但我在这篇文章中找不到我的答案。我的问题是关于“堆叠”别名
  • 如果你在命名空间外使用using Histogram = EmpiricScore&lt;int&gt;;,那么using FeatureHistogram = Dictionary&lt;string, Histogram&gt;; 在命名空间内是可能的。但这不是更深层次依赖的答案。
  • 啊我没注意到,请忽略

标签: c# templates alias


【解决方案1】:

但编译器不会这样做。为什么?

编译器不会按照 C# 规范 9.4.1 执行此操作:

using-alias-directive 引入了一个标识符,用作紧接的编译单元或命名空间主体内的命名空间或类型的别名。

using-alias-directive:
using   identifier   =   namespace-or-type-name   ;

using-alias-directives 的写入顺序没有意义,using-alias-directive 引用的namespace-or-type-name 的分辨率不受using-alias-directive 本身或直接包含的编译单元中其他using-directives 的影响或命名空间主体。

换句话说,using-alias-directivenamespace-or-type-name 被解析为好像直接包含的编译单元或命名空间主体没有使用指令。

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

选项: 1.正如M.kazem Akhgary在评论中建议的那样,定义新的命名空间

demo

using Histogram = System.Collections.Generic.List<int>;

namespace TEST
{
    using FeatureHistogram = System.Collections.Generic.Dictionary<string, Histogram>;

    public class Program
    {    
        public static void Main()
        {
            var x = new Histogram();
            Console.WriteLine(x.GetType());

            var y = new FeatureHistogram();
            Console.WriteLine(y.GetType());
        }   
    }
}
  1. 为更深层次的依赖创建类

【讨论】:

    【解决方案2】:

    创建新类似乎有点矫枉过正......

    我不认为这是一种矫枉过正,因为如果你设计一个包装 Dictionary&lt;string, Histogram&gt; 的类(你的类应该实现 IDictionary&lt;string, Histogram&gt; 并有一个私有的 Dictionary&lt;string, Histogram&gt; 属性支持数据)你正在执行 可重用性,这是面向对象编程的最大卖点之一。

    例如,您的实现如下所示:

    public class FeatureHistorgram : IDictionary<string, Historam>
    {
        private readonly Dictionary<string, Histogram> _data = new Dictionary<string, Histogram>();
    
        public void Add(string key, Histogram value)
        {
            _data.Add(key, value);
        }
    
        // ... and the rest of IDictionary<TKey, TValue> interface members...
    }
    

    【讨论】:

    • 问题:是实现IDictionary还是继承Dictionary更好?如果不阅读您的答案,我会使用后者(并避免使用_data 并改用base)。
    • @XavierPeña 好吧,这取决于具体情况。如果您想自定义如何将项目添加到基础字典中,那么界面方法是正确的方法。如果您不打算在将项目添加到字典之前/之后做某事,那么派生 Dictionary&lt;TKey, TValue&gt; 应该就足够了......
    • “如果你想自定义如何将项目添加到底层字典中,接口方法是正确的”:那么在Dictionary继承中覆盖Add的缺点是什么? (在试图提出这个问题时,我意识到在 SO 中听起来不像一个聪明人是多么困难......根本不是我的意图,只是想学习)
    • @XavierPeña 你应该阅读文档。 Add 不是虚拟方法:msdn.microsoft.com/es-es/library/k7z0zy8k(v=vs.110).aspx
    • 这不是矫枉过正的问题,重要的部分似乎是在声明一个新类时,它将不再与原始冗长的类名双边分配兼容,而不是一个别名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-14
    • 2019-01-29
    • 2014-01-17
    • 2022-11-15
    • 1970-01-01
    相关资源
    最近更新 更多