.Net中的类型转发:转发的类是否需要继承Type类?

ric*_*ard 3 c# types forwarding

如果要将类引用转发给具有类型转发的另一个程序集,该类是否需要从Type继承?

我想我真正追求的是 - 类型转发的短语和概念中的"类型"一词是什么意思,或者说的是什么.

Eri*_*ert 13

如果要将类引用转发给具有类型转发的另一个程序集,该类是否需要从Type继承?

没有.

我想我真正追求的是 - 类型转发的短语和概念中的"类型"一词是什么意思,或者说的是什么.

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

解决方案是将类型Foo移动到Bravo,然后运送新版本的Alpha,其中包含一个类型转发器,告诉Alpha用户"如果您正在寻找Foo,它现在可以在Bravo中找到".这样你就不会打破那些依赖于过去的方式的人.

我认为我在这里缺少的是"类型"的定义在类型转发的概念中.有什么资格作为一种类型?

以下是类型定义:

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

以下是类型引用(它们都引用另一种类型;这些类型都没有定义新内容.)

  • 构造了泛型类,结构,接口和委托
  • 阵列
  • 指针
  • nullables

(并且有一种类型不属于任何一种类型,即返回类型"void".)

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

你是什​​么意思"未构造的泛型类?这是否只是一个泛型的定义,而不是一个已经用指定的类型实例化的泛型?

正确.

你能指点我找到"类型参考"和"类型定义"的信息吗?

这些不是C#语言规范的概念; 相反,这些是来自底层公共语言基础设施类型系统的概念.有关CLI在定义类型和引用类型之间的差异的广泛技术观察,请阅读ECMA 335 CLI规范,特别是查找有关TypeDef和TypeRef的元数据表的部分.


Jon*_*eet 8

这是一个有点令人困惑的话题,所以这是一个循序渐进的例子 - 现在使用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");
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    test.cs中

    class Test
    {
        static void Main()
        {
            Foo.Report();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 构建Alpha.dll:

    csc /target:library /out:Alpha.dll Foo.cs
    
    Run Code Online (Sandbox Code Playgroud)
  3. 构建Test.exe

    csc /r:Alpha.dll Test.cs
    
    Run Code Online (Sandbox Code Playgroud)
  4. 运行Test.exe - 你应该得到明显的输出

  5. 构建Bravo.dll:

    csc /target:library /out:Bravo.dll Foo.cs
    
    Run Code Online (Sandbox Code Playgroud)
  6. 创建一个新文件Forwarding.cs:

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

    csc /r:Bravo.dll /target:library /out:Alpha.dll Forwarding.cs
    
    Run Code Online (Sandbox Code Playgroud)

    请注意我们不再包含Alpha中的Foo代码.

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

    如果您查看Test.exe,它仍将引用Alpha.如果您查看Alpha.dll,您会发现Foo类型的代码不再存在......只有通过类型转发它才会挂起.