Type Forwarding in .Net: Does the class forwarded

2019-05-22 08:40发布

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.

2条回答
Viruses.
2楼-- · 2019-05-22 08:54

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.

查看更多
甜甜的少女心
3楼-- · 2019-05-22 09:10

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.

查看更多
登录 后发表回答