2012-01-27 23 views
1

私は、カスタムの代わりにマーカーインタフェース属性を使用するクラスに名前を付けるにはどうすればいいですか?

public class FooAssignableAttribute : Attribute 
{ 
    ... 
} 

[FooAssignable] 
public class Foo 
{  
    ... 
} 

属性コーディングだが、私はこのような辞書をコーディングすることができませんか?

Dictionary<string, FooAssignable> dictionary; 

マーカーインターフェイスを避けるために、カスタムアトリビュートを使用しようとしています。なぜ私は上記のコードを書くことができないのですか?

+0

これはできません。属性はC#の型システムの一部ではありませんが、これはあなたができる制限ではありません。なぜあなたは属性に基づいてこの制約を表現する必要がありますか? – millimoose

+0

そして?だから、あなたはしたくないですが、これは何をする必要がありますか...何が問題なのですか? –

+0

あなたのコードサンプルをフォーマットしました。将来的には、コードサンプルを適切に表示するために4つのスペースをインデントする必要があります(または、エディットボックスの上の '{}'ボタンを使用することもできます)。 –

答えて

2

いいえ、これは機能しません。 C#の汎用コレクション(またはその他の汎用)のパラメトリック型は、宣言可能な型でなければならず、属性はメタデータとしてのみ存在します。

FooAssignable型のオブジェクトは使用できません。 FooAssignable属性を持つオブジェクトを持つことはできますが、これはスーパータイプと同じではありません。 FooAssignableはクラスまたはインタフェースではなく、有効な型指定子ではありません。 FooAssignableAttributeはありますが、これは属性自体を参照する型であり、その属性でタグ付けされた項目ではありません。

ディクショナリでは、インデクサのアウトタイプは、提供したアウトタイプです。しかし、FooAssignable型の変数を持つことはできません.FooAssignableでタグ付けされた型の変数を持つことはできますが、すべての型が適合する単一の基底クラスは存在しません。この型宣言は不正であるため、このディクショナリは、他の多くの場所でインデクサからのゲッタの戻り値の型として、違法で存在しない型を持ちます。 C#型チェックは、属性の存在チェックを持つ汎用メカニズムを使用して自発的に置き換えることはできません。

タイプシステムで確認する必要があるものはすべて、タイプシステムの一部である必要があります。属性評価では型が定義されていないので、型システムではこれを行うことはできません。一方、ジェネリックスは、型システムと最も直接的に相互作用する言語の一部です。このようなチェックを行うためには、実際に型システムを調べなければなりません。その代わりに、FooAssignableAttributeをインターフェイス(IFooAssignable?)に昇格させることを意味します。

+0

私はそれを知らなかった。しかし、最後の文についてもっと教えていただけますか? –

+0

私が理解しているように、FooAssignable属性を持つオブジェクトに文字列をマップする辞書が必要です。それは不可能です。なぜなら、FooAssignableAttribute型は属性自体を参照するだけで、「FooAssignable属性を持つオブジェクト」を意味するわけではありません。しかし、マーカーインターフェースIFooAssignableを作成し、FooAssignableAttributeを実装したすべてのものを作成する場合は、文字列をIFooAssignableにすることができます。 IFooAssignableは、使用できるオブジェクトができる型です。一般的なコレクションには "is a"が必要ですが、属性との関係は "has a"です。 –

+0

+1 OPが答えを切り替えてからあなたが彼を理解したように見えます。 – LarsTech

1

FooAssignableAttributeは、クラスの名前です。コード内のクラスを参照したい場合は、そのクラスの名前を使用する必要があります。あなたは上記のご[FooAssignable]例のように、それをなどの属性を使用しているとき

末尾をオフのままの速記「Attributeは」のみ動作します。変数宣言やジェネリック型の引数など、クラスとして使用する場合は、そのクラス名を使用する必要があります。

public class FooAssignable : Attribute 
{ ... } 
1

ただ、(可能ならば)自分のクラス名を変更します。

+0

これは問題に対処していません - Darf Zonは(FooAssignable型のオブジェクトである)コレクションではなく、FooAssignableでタグ付けされたオブジェクトのコレクションを必要としています。これはスコープの問題であり、FooAssignableを実装する単一のスーパークラスがないため、インターフェイスなしでこれを行う方法はありません。 –

+0

@AdamNorberg私が答えたとき、ジョー・ホワイトはそれをかなり覆しました。その質問のリビジョン履歴を見ると、最初は、属性名がクラスを装飾する方法のように、キーワードの最後に「属性」拡張子を付けずにクラス名を使用しようとしていました。私が知る限り、アトリビュートには「アトリビュート」という名前で終わらなければならないというルールはありません。彼は本当に長い名前を望んでいないので、OPに別のオプションを与えるだけです。 – LarsTech

+0

質問は私が答える途中で書き直されました。私は、苦情は名前の長さではなく、収集されるFooAssignableAttributeのオブジェクトではなく、代わりに「FooAssignableAttributeでタグ付けされたオブジェクトのオブジェクト」でなければならないと仮定しました。タイプ。私はあなたの答えの受け入れに基づいて、それを間違って読んだようです! –

0

は、独自のスタイルガイドとコヒーレントであるか、存在するすべてのスタイルガイドを選択します。

+0

これはスタイルの問題ではありません。これはC#型システムの基本であり、バインドされた属性は型ではありません。属性型は存在しますが、objects-tag-with-an-attributeは代入可能型ではありません。 –