2011-07-21 15 views
0

私はC#を教えているので、これがやや明白であれば私を許してください。ジェネリック型の属性を参照していますか?

私は構造体の配列を渡すことができ、構造体の属性の1つを使用できる汎用関数を記述しようとしています。私は必要な方法で属性を参照できるように、関数内に汎用データ型を宣言する方法は知らない。

多分、コードでよりうまく伝えることができます。これは、私がやろうとしていることを説明するために機能しないものです。実際に書く方法を知らなくても、それは渡される構造体の属性を指定している間、通常は呼び出すことができます。

int NewVariable = AFunctionIsThis<ThisIsAStruct, ThisIsAStruct.AnIntAttribute>(ThisIsADeclaredStruct); 

大変ありがとう、

Hanii子犬。

答えて

0

(で始まる単語「属性」はOOPの意味から.NETで異なる意味を持っていることに注意すること。)

それぞれ、メンバーを取得して設定するConverter<T,int>Action<T,int>デリゲートを使用してください。

public static int AFunctionIsThis<DataType>(DataType passedrecord, Converter<DataType,int> getter) 
{ 
    temp = getter(passedrecord) * 2 + 1; 

    return temp; 
} 

、その後、あなたはまた、値を設定する必要がある場合

AFunctionIsThis(ThisIsADeclaredStruct, x => x.AnIntProperty); 

それを呼び出す、あなたは

AFunctionIsThis(ThisIsADeclaredStruct, x => x.AnIntProperty, (x, v) => { x.AnIntProperty = v; }); 

を使用するか、メンバ参照をヤンクするExpression<Converter<T>>でいくつかの魔法を行うことができますし、一致するセッターを作成します。

+0

これは私が行ったことです。しかし、私があなたが示した方法で関数を呼び出そうとすると、これは私が得るものです:http://img41.imageshack.us/img41/6566/screenshot20110804at084.png –

+0

EDIT:わかりました 'static public void Hierarchical (refデータ型[]テーブル、コンバーター ID、コンバーター SubordinateTo)' このコードを使用して関数を宣言すると、関数を呼び出すには: 'Sort.Hierarchical(ref Categories.Category、ID =>カテゴリ、カテゴリ=カテゴリ、SubordinateTo =>カテゴリ。カテゴリ。] SubordinateTo); ' 私は変換するアイテムを配列として宣言してください - どうすればよいかわかりません^ _^;; ありがとうございます! –

+0

@ハニイ:実際には、あなたはコンバーターに配列を渡す必要があると考えることがあなたの問題です。あなたのソート関数は配列の個々の要素を引っ張ってそれをコンバーターに渡し、個々のIDを取得します。 'Sort.Hierarchical(Category.Category、c => c.ID、c => c.SubordinateTo);を試してみてください。配列が参照型なので、配列パラメータを参照渡しする必要はありません。 –

0

Hanii子犬:要するに

、はい、あなたは何をしているかを行うことができる必要がありますが、ここで働く構文は次のとおりです。

public static int AFunctionIsThis<T>(T passedRecord) where T : DataType 
{ 
    var temp = passedRecord.Value; 
    return temp; 
} 

public class DataType 
{ 
    public int Value { get; set; } 
} 

お役に立てば幸いです。 Dave

+0

これは、私が欲しいものを達成するための最も簡単な方法のようですが、私はその関数を呼び出して、Valueで表現したい構造体の属性をどのように指定しますか?または、渡された構造体に "Value"という名前の属性が必要ですか? –

+0

Hanii Puppy:正直なところ、構造体のプロパティにアクセスできることを保証したい場合は、構造体にGuffaのようなインタフェースを実装させるようにしてください。構造体やクラスに渡すものはすべてそのプロパティになります。 – davecoulter

0

あなたがしたいことは、特定のインターフェイスを実装しているTを受け入れる、またはValueというintメンバを持つ特定の基本クラスから派生したTのみを受け入れる汎用メソッドを定義することです。 例えば:

public interface IClass { int Value{get;set;} } 
    public class ExampleImpl : IClass 
    { 
     int Value{get;set;} 
     /* Additional Members\methods here */ 
    } 
    public class HelperClass 
    { 
    public static int GenMethod<T>(T item) where T:IClass 
    { 
     return item.Value * 2 + 1; 
    } 
    } 
1

あなたが唯一の汎用的なデータ型を指定することができ、一般的なタイプが含まれている必要がありますメンバーを指定することはできません。あなたの構造体は、その後インタフェースを実装し、そしてあなたは、一般的なデータ型としてインターフェイスを指定することができます

public interface IHaveValue { 
    int Value { get; } 
} 

public static int AFunctionIsThis<T>(T passedrecord) where T : IHaveValue { 
    return passedrecord.Value * 2 + 1; 
} 

しかし

あなたは、プロパティが定義されているインタフェースを使用しますあなたが使用しているものでは、ジェネリックをまったく使用する必要はありません。

public static int AFunctionIsThis(IHaveValue passedrecord) { 
    return passedrecord.Value * 2 + 1; 
} 

構造体を使用するのではなく、クラスを使用することをお勧めします。構造体は正しく実装するのがより複雑なので、構造体を使用する本当の理由があるまでクラスに固執する必要があります。

+0

そして、人々は依然としてScalaの型システムがC#/ F#よりももっと豊かであるかと尋ねています:) – Grozz

+0

私は最後の1時間程度の間、インターフェイスを抱いていました。 機能を正常に呼び出すと、ボクシングの変換がないというエラーが表示されます。私は、インターフェイスのどのフィールドが構造体のフィールドを表すかを指定するはずですが、それを行う方法はわかりません。 また、ビルドしようとすると(エラーをコピーして貼り付けようとしていましたが)、「インターフェイスにフィールドを含めることができません」というように、インターフェイスに宣言されている各変数の下にエラーが表示されます。 –

+0

右のインターフェイスにはフィールドを設定できないため、プロパティを使用する必要があります。上記のコードを修正しました。インターフェースと実装タイプとの間の識別は名前によるものであり、つまり、インターフェースと同じ名前のプロパティーを作成するだけです。 – Guffa

関連する問題