Why do `Assembly` and `Module` have no publicly de

2019-05-28 17:12发布

I'm building a .NET assembly loader in C# for an "experiment"/learning more about .NET internal operations. I've implemented the reflection API by deriving types like:

  • RuntimeType : Type
  • RuntimeFieldInfo : FieldInfo
  • RuntimeMethodInfo : MethodInfo
  • RuntimeParameterInfo : ParameterInfo
  • RuntimeConstructorInfo : ConstructorInfo
  • RuntimePropertyInfo : PropertyInfo

Unfortunately I'm having trouble because the following have no publicly accessible constructors, so I can't derive from them:

  • Assembly (not sealed - AssemblyBuilder is internally derived from it)
  • Module (not sealed - ModuleBuilder is internally derived from it)

I need something to return from RuntimeType.get_Assembly and RuntimeType.get_Module. Suggestions? Get creative - I've had to. ;) For creating RuntimeTypeHandle instances, some unsafe casting of pointers gets the job done, but it's not so easy here.

As an aside: The particular trouble now is I'm trying to pretty-print the IL for the loaded types. For constructed generics, the Type.FullName property includes the generic parameters via the AssemblyQualifiedName property, which in turn relies on the Assembly property.

1条回答
贪生不怕死
2楼-- · 2019-05-28 18:10

Why can't you derive from them? Both of the types (Assembly and Module) have a protected constructor that will be available to your derived type. The types themselves are public so there is no issue with it being less visible than the actual specifier.

The following code compiles just fine

public class MyAssembly : System.Reflection.Assembly {
    public MyAssembly() : base() {}
}

As to why they don't have any public constructors. I don't have any direct knowledge of this but it seems clear they wanted to force people to derive from these classes. It does seem odd considering they have no abstract members. The only thing I can think of is a versioning issue but no logic behind that is jumping to my mind right now.

EDIT

After I read 280Z28's comment I checked and yes this is new to .Net 4.0. Prior to 4.0 the constructor for both Assembly and Module was internal and both types were concrete but not sealed. So derivation prior to 4.0 is not possible without doing some evilness with fully trusted code.

查看更多
登录 后发表回答