【问题标题】:Type Forwarding in .Net: Does the class forwarded need to inherit from the Type class?.Net 中的类型转发:转发的类是否需要继承自 Type 类?
【发布时间】:2011-06-05 20:57:12
【问题描述】:

如果您想通过类型转发将类引用转发到另一个程序集,该类是否需要从 Type 继承?

我想我真正追求的是 - 类型转发的短语和概念中的“类型”一词是什么意思,或表示什么。

【问题讨论】:

    标签: c# .net types forwarding


    【解决方案1】:

    如果您想通过类型转发将类引用转发到另一个程序集,该类是否需要从 Type 继承?

    没有。

    我想我真正追求的是 - 类型转发的短语和概念中的“类型”一词是什么意思,或表示什么。

    假设您在汇编 Alpha 中有一个 Foo 类型,并且在您的下一个版本中,您意识到 Foo 确实应该在汇编 Bravo 中。您不能移动该类型,因为所有依赖 Foo 处于 Alpha 中的客户都将被破坏。

    解决方案是将类型 Foo 移动到 Bravo 中,然后发布一个新版本的 Alpha,其中包含一个类型转发器,告诉 Alpha 的用户“如果你正在寻找 Foo,它现在可以在 Bravo 中找到”。这样一来,您就不会破坏任何依赖于过去的事物的人。

    我认为我在这里缺少的是类型转发概念中“类型”的定义。什么是类型?

    以下是类型定义

    • 非泛型或未构造的泛型类、结构、接口和委托
    • 枚举

    以下内容是类型引用(它们都引用另一种类型;这些都定义新的东西。)

    • 构造的泛型类、结构、接口和委托
    • 数组
    • 指针
    • 可为空的

    (并且有一种类型不属于任何一个类别,即返回类型“void”。)

    在所有这些类型中,只有类型定义可以被转发。类型转发器的目的是说“以前由该程序集定义的类型现在由该程序集定义”,因此只有转发类型定义才有意义。不能转发类型MyStruct<int>[];这没有任何意义。你可以转发MyStruct<T>

    “未构造的泛型类”是什么意思?这是否仅意味着泛型的定义,而不是已使用指定类型实例化的泛型?

    正确。

    你能指出你在哪里找到“类型引用”和“类型定义”的信息吗?

    这些不是 C# 语言规范中的概念;相反,这些是来自底层公共语言基础结构类型系统的概念。如需深入了解 CLI 在定义类型和引用类型之间的区别,请阅读 ECMA 335 CLI 规范,尤其是有关 TypeDef 和 TypeRef 元数据表的部分。

    【讨论】:

    • 我刚刚编辑了我的问题,原因是我问的原因。 . .大声笑类型转发并不意味着我只能转发类型,如值或引用类型,如 Int、Double、Long 等——它意味着别的东西。这是什么意思?
    • @Richard:不,这恰恰意味着 - 它基本上是将一个程序集中特定类型的任何引用转发到另一个程序集中的类型。举个例子会有帮助吗?
    • 我想我在这里缺少的是类型转发概念中“类型”的定义。什么是类型?
    • @Richard DesLonde:与正常情况相同 - 类、结构、枚举、接口等。有关 Eric 所说的具体示例,请参阅我的答案。 (我会检查并编辑我的名字以匹配 Eric 的名字。)
    • 谢谢你们。这就是我要找的埃里克。现在说得通了。我现在唯一的问题是,“未构造的泛型类......等等”是什么意思?这是否仅意味着泛型的定义,而不是已使用指定类型实例化的泛型?你能指出我在哪里找到“类型引用”和“类型定义”的信息吗?我在任何地方都找不到类似的东西。
    【解决方案2】:

    这是一个有点令人困惑的话题,所以这里有一个分步示例 - 现在使用 Eric 答案中的名称来帮助保持一致。我们将从一个库 (Alpha.dll) 开始并构建一个依赖于 Alpha 的应用程序 (Test.exe)。然后,我们将 Test.exe 所依赖的类型 (Foo) 放入不同的库 (Bravo.dll) 中,而无需重新编译 Test.exe。

    1. 创建以下文件:

      Foo.cs

      using System;
      
      public class Foo
      {
          public static void Report()
          {
              Console.WriteLine("Foo.Report");
          }
      }
      

      Test.cs

      class Test
      {
          static void Main()
          {
              Foo.Report();
          }
      }
      
    2. 构建 Alpha.dll:

      csc /target:library /out:Alpha.dll Foo.cs
      
    3. 构建测试.exe

      csc /r:Alpha.dll Test.cs
      
    4. 运行 Test.exe - 你应该得到明显的输出

    5. 构建 Bravo.dll:

      csc /target:library /out:Bravo.dll Foo.cs
      
    6. 创建一个新文件,Forwarding.cs

      using System.Runtime.CompilerServices;
      [assembly:TypeForwardedTo(typeof(Foo))]
      
    7. 重新编译Alpha.dll:

      csc /r:Bravo.dll /target:library /out:Alpha.dll Forwarding.cs
      

      请注意我们如何不再在 Alpha 中包含 Foo 的代码。

    8. 运行 Test.exe - 它仍然可以工作,尽管 Test.exe 要求 在 Alpha.dll 中引用 Foo...CLR 只是将其重定向到 Bravo.dll。

      如果您查看 Test.exe,它仍然指的是 Alpha。如果你查看 Alpha.dll,你会发现 Foo 类型的代码已经不存在了……只是通过类型转发,它们都挂在一起了。

    【讨论】:

    • 顺便说一句,感谢乔恩的好例子。我真的很喜欢“类型转发”的“类型”部分。我现在明白了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    相关资源
    最近更新 更多