【问题标题】:C# public type alias?C#公共类型别名?
【发布时间】:2011-08-12 05:18:05
【问题描述】:

我想做的是在一个新的命名空间中用 C# 编写一些类,作为另一个命名空间中的类的包装类。有时不需要包装类,但我仍然想要新命名空间中的相应类。我想要一个准确的课程副本。有没有办法通过引用另一个类的定义来定义新命名空间中的类?换句话说,我想要一个别名。

为了澄清我的意思,如果现有命名空间被命名为“Namespace1”而新命名空间被命名为“Namespace2”,在 Namespace2 中使用如下代码:

using Class1 = Namespace1.Class1;

不会工作,因为Namespace2.Class1 不存在。 Class1 只会被别名为“私有”到 Namespace2,而不是“公共”到 Namespace2。如果我可以在命名空间之外使用Namepsace2.Class1,并且如果它仍然引用Namespace1.Class1,那么这就是我想要的。

我认为可能有一种方法可以通过属性或反射来实现这一点。如果有一些预处理器指令或宏可以复制也可以工作的代码,但显然 C# 没有这样的东西。

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    你可以使用create an alias to a type:

    using Project = PC.MyCompany.Project;
    

    【讨论】:

    • 这只是一个编译器技巧,但实际上并没有“复制”另一个命名空间中的类。
    • @Reed Copsey - 我明白你的意思。我不确定他所说的“精确副本”是指真正的副本还是只是看起来像副本的东西。 @YWE - 你能澄清一下吗?
    • 是的 - 目前还不清楚。我采取了另一种方式,因为他在问题中指定了“公共”(这对于类型别名没有意义)并且因为他引用了“可选包装类”......听起来他想要一个“复制”另一个命名空间的 API。
    • 等。很抱歉不清楚。希望我编辑了我的问题以添加一些说明。我确实需要另一个命名空间中的类的“副本”。而且你建议的那种别名在我的情况下不起作用。
    【解决方案2】:

    听起来您需要将一个类定义映射到另一个。

    这可以手动完成(通过大量样板代码)或通过像AutoMapper 这样的工具自动完成。

    【讨论】:

      【解决方案3】:

      如果您在不同的命名空间中定义类,它将是不同的类。 MyNewNamespace.MyClassMyOldNamespace.MyClass 是 .NET 中的两种不同类型。

      您可以轻松地将所有第一个类的公共 API 封装在新类中,但这需要一些样板代码。 AOP 可以提供一种更简单的方法,使用类似 PostSharp 的东西(带有自定义过滤器)。

      【讨论】:

        【解决方案4】:

        你可以继承类:

        namespace N2
        {
           public class Class1 : N1.Class1
           { }
        }
        

        【讨论】:

        • 甚至共享一个界面。 +1。
        【解决方案5】:

        是的,如果我在msdn article on alias namespacing这里理解正确的话,你可以这样做

        这就是魔法

        using colAlias = System.Collections
        

        所以我在自己的命名空间下为 System.Collections 起别名。

        这里是例子

        using colAlias = System.Collections;
        namespace System
        {
            class TestClass
            {
                static void Main()
                {
                    // Searching the alias:
                    colAlias::Hashtable test = new colAlias::Hashtable();
                // Add items to the table.
                test.Add("A", "1");
                test.Add("B", "2");
                test.Add("C", "3");
        
                foreach (string name in test.Keys)
                {
                    // Seaching the gloabal namespace:
                    global::System.Console.WriteLine(name + " " + test[name]);
                }
            }
        }
        

        }

        【讨论】:

          【解决方案6】:

          WRT 包装类,我发现很多时候人们包装类只是为了扩展功能,而不是用它来表达 is-a 关系。 对于这些情况,您可以考虑Extension Methods

          这允许您为现有类编写方法,而不是仅仅为了添加更多功能而派生。例如。

          /// <summary>
          /// ICollectionExtensions
          /// </summary>
          internal static class ICollectionExtensions
          {
              public static void AddNew<T>(this ICollection<T> self, T data)
              {
                  if (self != null && !self.Contains(data))
                  {
                      self.Add(data);
                  }
              }
          }
          

          然后,您可以在ICollection&lt;T&gt; 类型上使用.AddNew()

          【讨论】:

            【解决方案7】:

            不确定您要完成什么,但也请查看AutoMapper

            【讨论】:

              猜你喜欢
              • 2020-03-18
              • 1970-01-01
              • 2020-03-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-11-10
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多