如何从程序集级属性引用私有类的类型?

发布于 2024-12-01 23:08:58 字数 1282 浏览 2 评论 0原文

我已经定义了一个程序集级属性类 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 技术交流群。

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

发布评论

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

评论(2

我家小可爱 2024-12-08 23:08:58

将其设为内部(您已经声明您不想这样做)是最省力的方法。对于大多数代码,允许 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, allowing MyClass 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 use typeof(MyClass).Assembly.GetType(fullName) - but then you lose the compiler validation that typeof 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.

深海里的那抹蓝 2024-12-08 23:08:58

您在最后几段中的断言是正确的。您的选择是:

  • 将嵌套类设置为内部以启用 typeof

  • FooAttribute 添加一个构造函数,该构造函数采用私有嵌套类的完全限定类型名称,然后使用反射来获取表示它的System.Type

例如:

public sealed class FooAttribute
{
    public FooAttribute(string id, string typeName)
    {
        var type = Type.GetType(typeName);

        // whatever the other ctor does with the System.Type...
    }
}

用法:

[assembly: Foo("Bar", typeof(Bar))]
[assembly: Foo("Baz", "Foo.Bar+Baz, MyAssembly")]

namespace Foo
{
    public class Bar
    {
        private class Baz
        {
        }
    }
}

Your assertions in your last paragraphs are correct. Your options would be to:

  • Make the nested class internal to enable typeof

or

  • Have an added constructor to FooAttribute which takes the fully qualified type name of the private nested class, and then uses reflection to get a System.Type representing it.

For instance:

public sealed class FooAttribute
{
    public FooAttribute(string id, string typeName)
    {
        var type = Type.GetType(typeName);

        // whatever the other ctor does with the System.Type...
    }
}

usage:

[assembly: Foo("Bar", typeof(Bar))]
[assembly: Foo("Baz", "Foo.Bar+Baz, MyAssembly")]

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