如何从程序集级属性引用私有类的类型?
我已经定义了一个程序集级属性类 FooAttribute
,如下所示:
namespace Bar
{
[System.AttributeUsage (System.AttributeTargets.Assembly, AllowMultiple=true)]
public sealed class FooAttribute : System.Attribute
{
public FooAttribute(string id, System.Type type)
{
// ...
}
}
}
并且我使用它来将 id 与类相关联,例如:
[assembly: Bar.Foo ("MyClass", typeof (Bar.MyClass))]
namespace Bar
{
public class MyClass
{
private class Mystery { }
}
}
这一切都正常。但是,如果我需要以某种方式引用 MyClass
中定义的私有类 Mystery
该怎么办?这有可能吗?尝试从顶级 [ assembly: ...] 指令引用它是行不通的,因为该类型不是公开可见的:
[assembly: Bar.Foo ("Mystery", typeof (Bar.MyClass.Mystery))] // won't work
并尝试将 [ assembly: ... ]
指令放入 MyClass
中,以便它可以看到 Mystery
不合法,因为 [assemble: ...]
必须是在顶层定义:
namespace Bar
{
class MyClass
{
[assembly: FooAttribute (...)] // won't work either
...
}
}
有一种方法可以从外部访问内部
类型通过将用户声明为程序集的朋友来引用程序集,但是在程序集中引用私有类型怎么样?我想这是不可能的,我只需将 Mystery
声明为 internal
即可,但我想确保我没有错过一些微妙之处。
I have defined an assembly level attribute class FooAttribute
like this:
namespace Bar
{
[System.AttributeUsage (System.AttributeTargets.Assembly, AllowMultiple=true)]
public sealed class FooAttribute : System.Attribute
{
public FooAttribute(string id, System.Type type)
{
// ...
}
}
}
and I use it to associate an id to classes, for instance:
[assembly: Bar.Foo ("MyClass", typeof (Bar.MyClass))]
namespace Bar
{
public class MyClass
{
private class Mystery { }
}
}
This all works fine. But what if I need to somehow reference the private class Mystery
, defined in MyClass
? Is this at all possible? Trying to reference it from the top-level [assembly: ...]
directive does not work, as the type is not publicly visible:
[assembly: Bar.Foo ("Mystery", typeof (Bar.MyClass.Mystery))] // won't work
And trying to put the [assembly: ...]
directive into MyClass
in so that it could see Mystery
is not legal, as [assembly: ...]
must be defined at the top level:
namespace Bar
{
class MyClass
{
[assembly: FooAttribute (...)] // won't work either
...
}
}
There is a way to access internal
types from outside of an assembly by declaring the user a friend of the assembly, but how about referencing private types inside an assembly? I guess it is not possible, and I just would have to declare Mystery
to be internal
instead, but I want to be sure I did not miss some subtlety.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
将其设为
内部
(您已经声明您不想这样做)是最省力的方法。对于大多数代码,允许MyClass
公开(通过静态属性)type 实例(即public static Type MysteryType { get { return typeof(Mystery) ; } }
可以,但是通过属性不会(只能使用一些基本类型的常量值)internal 的唯一替代方案 。 code>,那么,就是将其编码为字符串文字,(即
[Foo("Bar.MyClass+Mystery")]
)并使用typeof(MyClass).Assembly.GetType(fullName) - 但随后您会失去
typeof
通常提供的编译器验证(另请注意运行时用于表示嵌套类型的+
,而不是。 这是 C# 的表示形式)
就我个人而言,我只是将其设为
内部
。Making it
internal
(which you already state you don't want to do) is the least effort approach. For the majority of code, allowingMyClass
to expose (via a static property) the type instance (i.e.public static Type MysteryType { get { return typeof(Mystery); } }
would work, but that won't work from an attribute (only constant values of a few basic types can be used).The only alternative to
internal
, then, is to code it as a string literal, (i.e.[Foo("Bar.MyClass+Mystery")]
) and usetypeof(MyClass).Assembly.GetType(fullName)
- but then you lose the compiler validation thattypeof
normally provides. (note also the+
that the runtime uses to represent nested types, not.
which is the C# representation)Personally, I'd just make it
internal
.您在最后几段中的断言是正确的。您的选择是:
typeof
或
FooAttribute
添加一个构造函数,该构造函数采用私有嵌套类的完全限定类型名称,然后使用反射来获取表示它的System.Type
。例如:
用法:
Your assertions in your last paragraphs are correct. Your options would be to:
typeof
or
FooAttribute
which takes the fully qualified type name of the private nested class, and then uses reflection to get aSystem.Type
representing it.For instance:
usage: