2012-01-28 6 views
1

ここでは、マーカーインターフェイスを回避する方法の例を示します。辞書のカスタム属性のマーカーインターフェイスを回避するには?

public class AssignableAttribute : Attribute { } 

[Assignable] 
public class Foo 
{  
    ... 
} 

[Assignable] 
public class Bar 
{  
    ... 
} 

これを辞書に追加しようとしていますが、どうしてこのような辞書をコード化できないのですか?

Dictionary<string, AssignableAttribute> dictionary = new ...(); 
dictionary.Add("foo", new Foo()); 
dictionary.Add("bar", new Bar()); 

マーカーインターフェース(無メンバーとのインタフェース)を使用しないでください。

カスタム属性は、タイプをマークする方法を提供します。カスタム属性についての詳細は、 を参照してください。カスタム属性の記述を参照してください。カスタム 属性は、コードが実行されるまで属性 のチェックを延期できる場合に優先されます。シナリオにコンパイル時に のチェックが必要な場合、このガイドラインを遵守することはできません。

http://msdn.microsoft.com/en-us/library/ms229022.aspx

+1

あなたはあるタイプの要素の辞書を宣言し、別の無関係なタイプの要素を追加しても動作しません。あなたの例から明らかではないので、達成しようとしていることの説明を記入してください。 –

+0

もう少しコードを追加しました。 – Darf

+0

@Darf:これはまだ解決しようとしている問題の説明ではありません。これはちょうどあなたがそれを解決しようとしている方法を示しています - そしてその方法はうまくいきません。 – ChrisWue

答えて

0

あなたは、「特定の属性が割り当てられている種類の辞書」のようなものを表現することはできません。タイプは、それに対して呼び出すことができる操作を提供します。型に属性を付けることで、操作を追加する必要はありません。基本的にメタデータを追加するだけです。マーカインタフェースを避けたいのであれば、これで解決しようとしている問題を正確に洗い出す必要があります。

編集

属性は、(彼らは追加の操作を追加しないでも、彼らはタイプの実装を変更します)タイプの振る舞いを変更しないでください。それらはクラス階層とは完全に直交しています。主に使用されているため、ある種のフレームワークは、実行時にあるタイプまたはそのメンバのいくつかの追加的な意味を推論することができます(たとえば、xml serialzierは、certinaメンバを直列化するか、特定のメンバを無視するための属性を介して伝えることができます)。ジェネリックのコンパイル・タイプの制約として属性を使用することはできません。というのも、特定の属性を持つすべての型をアタッチできるからです(コンパイラは基本的にそれをチェックできません)。

+0

わかりません。ここでの解決策はマーカーインターフェイスを作成することですが、.NET Guidenessはカスタム属性が良い方法であることを教えています。 – Darf

+0

@Darf、どのような問題の解決策ですか?問題が「どこかでマーカーインターフェイスを使用したい」の場合は、それを使用してください。それ以外の場合は、あなたが解決しようとしている実際の問題がおそらくあります。あなたがそれを綴らない限り、誰もあなたを助けることができません。 –

+0

@Darf:もう少し明確にしようとしました。 – ChrisWue

0

タイプは属性とは関係ありません。

IFooと呼ばれるインターフェイスを使用する必要があります。

interface IFoo 
{ 
    // various methods 
} 

public class Foo : IFoo 
{ 
} 

public class Bar : IFoo { } 

と辞書

Dictionary<string, IFoo> dictionary = new ...(); 
dictionary.Add("foo", new Foo()); 
dictionary.Add("bar", new Bar()); 
+0

投稿を更新しました – Darf

+0

このトリックはインターフェイスを使用しています。詳細については、http://msdn.microsoft.com/en-us/library/87d83y5b(v=vs.80).aspxを参照してください。 –

+0

これは私が理解できないものです。私は同じやり方をしていましたが、.NETのguidenessプラクティスはマーカインタフェースを記述するのは悪い習慣です。 – Darf

0

あなたは、オブジェクトの辞書を作ることができるインタフェースを使用して、ちょうどあなたの辞書に追加する前に、型が指定されたAssignableAttributeを持っているかどうかを確認したくない場合

Dictionary<string, object> dictionary = ...; 


private void AddAssignable(object assignableObject) 
{ 
    var type = assignableObject.GetType(); 
    if (type.GetCustomAttributes(typeof(AssignableAttribute), true) == null) 
     return; 

    dictionary.Add(type.Name, assignableObject); 
} 
0

あなたが利用できるフレームワークを最大限に活用していないようです。マーカーインターフェイスを持たないソリューションは、のマーカではなく、のインターフェイスを持つことです。

EDITAssignable属性については少し不明ですが、それは変換やデシリアライズの一種だと思いますか?

どうすればいいですか:汎用インターフェイスIAssignableFrom<T>Assignable属性を設定してください。あなたは、コードが実行されるまで、属性のチェックを延期することができたときに

interface IAssignableFrom<T> { 
    void AssignFrom(T source); 
} 

public class Bar : IAssignableFrom<Foo> { 
    public void AssignFrom(Foo foo){ 
    //implementation of assignment here 
    } 
} 

public class Baz : IAssignableFrom<Foo> { 
    public void AssignFrom(Foo foo){ 
    //implementation of assignment here 
    } 
} 

public class Foo : IAssignableFrom<Foo> { 
    public void AssignFrom(Foo foo){ 
    //implementation of assignment here 
    } 
} 

public class Program { 
    public static void Main(string[] args){ 
    IDictionary<string, IAssignableFrom<Foo>> dictionary = new Dictionary<string, IAssignableFrom<Foo>>; 

    dictionary.Add("foo", new Foo()); 
    dictionary.Add("bar", new Bar()); 
    dictionary.Add("baz", new Baz()); 
    } 
} 
3

カスタム属性が好ましいです。 シナリオでコンパイル時のチェックが必要な場合、このガイドラインに準拠することはできません。

これが鍵です。そのようなジェネリックを使用しようとすると、コンパイル時のチェックが使用されています。 Dictionary<string, Object>でランタイムチェックを延期することができますが、特別な状況がなければ誰もそれを好まないと思います。

ガイドラインは推奨事項であり、遵守する必要はありません。この特定のガイドラインは、ではなく、である必要があります。

関連する問題