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としてコーディングして-を使用することですが、通常提供されるコンパイラの検証が失われます。( C# 表現ではなく、ランタイムがネストされた型を表すために使用する にも注意してください)[Foo("Bar.MyClass+Mystery")]typeof(MyClass).Assembly.GetType(fullName)typeof+.

個人的には、私はちょうどそれを作るだろうinternal.

于 2011-08-30T08:30:27.857 に答える
2

最後の段落の主張は正しいです。あなたのオプションは次のとおりです。

  • ネストされたクラスを internal にして有効にします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 に答える