3

我已经定义了一个程序集级属性类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 { }
    }
}

这一切都很好。但是,如果我需要以某种方式引用Mystery定义在中的私有类MyClass怎么办?这是可能吗?试图从顶级[assembly: ...]指令中引用它是行不通的,因为该类型不是公开可见的:

[assembly: Bar.Foo ("Mystery", typeof (Bar.MyClass.Mystery))] // won't work

并且试图将[assembly: ...]指令放入MyClass其中以便它可以看到Mystery是不合法的,[assembly: ...]必须在顶层定义:

namespace Bar
{
    class MyClass
    {
        [assembly: FooAttribute (...)] // won't work either
        ...
    }
}

有一种方法可以通过将用户声明为程序集的朋友internal来从程序集外部访问类型,但是在程序集中引用私有类型呢?我想这是不可能的,我只需要声明是,但我想确保我没有错过一些微妙之处。Mysteryinternal

4

2 回答 2

4

实现它internal(您已经声明您不想这样做)是最省力的方法。对于大多数代码,允许MyClass公开(通过静态属性)类型实例(即public static Type MysteryType { get { return typeof(Mystery); } }可以工作,但不能从属性工作(只能使用一些基本类型的常量值)。

那么,唯一的替代方法internal是将其编码为字符串文字, (ie [Foo("Bar.MyClass+Mystery")]) 并使用- 但是您会丢失通常提供typeof(MyClass).Assembly.GetType(fullName)的编译器验证。typeof(还要注意+运行时用来表示嵌套类型,而不是.C# 表示)

就个人而言,我会成功的internal

于 2011-08-30T08:30:27.857 回答
2

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

  • 使嵌套类内部启用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
        {
        }
    }
}
于 2011-08-30T08:31:55.917 回答