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

发布于 2024-10-11 08:25:37 字数 96 浏览 5 评论 0原文

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

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

If you want to forward a class reference to another assembly with Type Forwarding, does that class need to inherit from Type?

I guess what I am really after is - What does it mean, or what is indicated, by the word "Type" in the phrase and concept of Type Forwarding.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无人问我粥可暖 2024-10-18 08:25:37

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

不。

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

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

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

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

以下内容是类型定义

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

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

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

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

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

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

正确。

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

这些不是 C# 语言规范中的概念;而是 C# 语言规范中的概念。相反,这些是来自底层公共语言基础结构类型系统的概念。要全面了解 CLI 在定义类型和引用类型之间有何不同,请阅读 ECMA 335 CLI 规范,特别是查找有关 TypeDef 和 TypeRef 元数据表的部分。

If you want to forward a class reference to another assembly with Type Forwarding, does that class need to inherit from Type?

No.

I guess what I am really after is - What does it mean, or what is indicated, by the word "Type" in the phrase and concept of Type Forwarding.

Suppose you have a type Foo in assembly Alpha, and in your next version you realize that Foo really should have been in assembly Bravo. You can't move the type because all your customers who have dependencies on Foo being in Alpha will be broken.

The solution is to move the type Foo into Bravo, and then ship a new version of Alpha that contains a type forwarder that tells users of Alpha "if you're looking for Foo, it's now found in Bravo". That way you don't break anyone who depends on things being the way they used to be.

I think what I am missing here, is what the definition of "Type" is in the concept of Type Forwarding. What qualifies as a type?

The following things are type definitions:

  • non-generic or unconstructed generic classes, structs, interfaces and delegates
  • enums

The following things are type references (they all refer to another type; none of these define something new.)

  • constructed generic classes, structs, interfaces and delegates
  • arrays
  • pointers
  • nullables

(And there is one type that does not fall into either category, which is the return type "void".)

Of all those types, only the type definitions can be forwarded. The purpose of a type forwarder is to say "the type that used to be defined by this assembly is now defined by that assembly", so it only makes sense to forward a type definition. You can't forward the type MyStruct<int>[]; that doesn't make any sense. You can forward MyStruct<T>.

what do you mean by "unconstructed generic classes? Does this mean only a generic's definition, and not a generic that has been instantiated with the type specified?

Correct.

And can you point me to where you found the information for the "type references" and "type definitions"?

These are not concepts from the C# language specification; rather, these are concepts from the underlying Common Language Infrastructure type system. For an extensive technical look at how the CLI differs between defined and referenced types, read the ECMA 335 CLI specification, particularly looking for the sections on the metadata tables for TypeDef and TypeRef.

霊感 2024-10-18 08:25:37

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

  1. 创建以下文件:

    Foo.cs

    使用系统;
    
    公共课 Foo
    {
        公共静态无效报告()
        {
            Console.WriteLine("Foo.Report");
        }
    }
    

    测试.cs

    类测试
    {
        静态无效Main()
        {
            Foo.Report();
        }
    }
    
  2. 构建 Alpha.dll:

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

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

  5. Build Bravo.dll:< /p>

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

    使用 System.Runtime.CompilerServices;
    [程序集: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 类型的代码不再存在...只是通过类型转发将它们全部挂在一起。

It's a slightly confusing topic, so here's a step-by-step example - now using the names from Eric's answer to help keep things consistent. We're going to start off with one library (Alpha.dll) and build an application (Test.exe) which depends on Alpha. We're then going to a type which Test.exe depends on (Foo) into a different library (Bravo.dll) without recompiling Test.exe.

  1. Create the following files:

    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. Build Alpha.dll:

    csc /target:library /out:Alpha.dll Foo.cs
    
  3. Build Test.exe

    csc /r:Alpha.dll Test.cs
    
  4. Run Test.exe - you should get the obvious output

  5. Build Bravo.dll:

    csc /target:library /out:Bravo.dll Foo.cs
    
  6. Create a new file, Forwarding.cs:

    using System.Runtime.CompilerServices;
    [assembly:TypeForwardedTo(typeof(Foo))]
    
  7. Recompile Alpha.dll:

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

    Note how we're not including the code for Foo in Alpha any more.

  8. Run Test.exe - it will still work, despite the fact that Test.exe asks for a reference to Foo within Alpha.dll... the CLR simply redirects that to Bravo.dll.

    If you look in Test.exe, it will still refer to Alpha. If you look in Alpha.dll, you'll find that the code for the Foo type isn't there any more... it's only through type forwarding that it all hangs together.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文