0

私のプログラムには、SortableObservableCollection<T>から継承するという名前のクラスがありObservableCollection<T>ます。と呼ばれる機能がありますSort

public void Sort<TKey>( Func<T, TKey> keySelector, int skip = 0 ) 
{
   // . . .
}

Key1typeという名前のプロパティを宣言したいと思いFunc<T, TKey>ます。私が試してみました:

public Func<T, TKey> Key1<T, TKey> { get; set; }

しかし、左中括弧で構文エラーが発生しています。このエラーは、コンパイラが左括弧を想定していることを示しています。私はそれをフィールド宣言にしてみました:

public Func<T, TKey> Key1<T, TKey>;

しかし、コンパイラはセミコロンで同じメッセージを表示します。

このプロパティを宣言するための正しい構文は何ですか?

4

5 に答える 5

3

ジェネリック プロパティを作成しようとしていますが、プロパティをジェネリックにすることはできません。どういうわけかそれを回避する必要があります。いくつかのオプションを考えることができます:

  1. デリゲートをobject-returningとして宣言します。

    public Func<T, object> Key1 { get; set; }
    
  2. プロパティをメソッド (ゲッターも必要な場合は 2 つのメソッド) にします。これの問題は、デリゲートを非ジェネリック フィールドに格納する必要があり、後でそれを操作するのが難しいことです。

    private Delegate key1;
    
    public void SetKey1<TKey>(Func<T, TKey> key1)
    {
        this.key1 = key1;
    }
    
  3. 並べ替えキーの型が変わらない場合は、クラスの型パラメーターにします。

    public class SortableObservableCollection<T, TKey>
    {
        public Func<T, TKey> Key1 { get; set; }
    
        …
    }
    
于 2013-02-02T18:25:43.897 に答える
3

まず、クラス定義を拡張して、メソッド レベルTKeyだけでなくジェネリック パラメーターを含める必要があります。Sort()

public class SortableObservableCollection<T, TKey>
{
}

その後、ジェネリック パラメーターの 2 番目のセットは必要ありません。

public Func<T, TKey> Key1 { get; set; }

メソッドからジェネリック パラメーターを削除することもできますSort()

于 2013-02-02T17:57:55.673 に答える
1

ここには2つのオプションがあります。まず、TKeyをジェネリックパラメーターとしてクラスに追加できます。

public class SortableObservableCollection<T, TKey> : ObservableCollection<T>
{
    public void Sort(Func<T, TKey> keySelector, int skip = 0)
    {
        //...
    }
    public Func<T, TKey> Key1 { get; set; }
}

クラスに別のジェネリックパラメーターを追加できない、または追加したくない場合の2番目のオプションは、Key1のプロパティを一緒に使用しないようにすることです。

public class Sort2<T> : ObservableCollection<T>
{
    Type keyType;
    object key1;

    public void Sort<TKey>(Func<T, TKey> selector, int skip = 0)
    {
        //...
    }

    public void SetKey<TKey>(TKey val)
    {
        keyType = typeof(TKey);
        key1 = val;
    }
    public TKey GetKey<TKey>()
    {
        return (TKey)key1;
    }

    public Type GetKeyType()
    {
        return keyType;
    }

}
于 2013-02-02T18:16:43.983 に答える
0

みんなの答えはうまくいくでしょうが、私がこれを手に入れようとしていたところに正確にはありませんでした. もともと、私はというクラスのメソッドを持っていましたSort:

public void Sort<TKey>( Func<T, TKey> keySelector, . . . ) {
    // . . .
}

これはうまくいきましたが、Sort メソッドを複数回呼び出すことに関連するバグが UI に見つかりました。並べ替え自体は機能しましたが、それは問題ではありませんでした。バグは複雑で説明が難しいので、私はそれについて詳しく説明したくありません。しかし、最も簡単な解決策は、コレクションが正しいキーで一度だけソートされるようにすることでした。問題は、コレクションがバインドされた特定のドロップダウンによってキーが異なることです。そのため、コレクション内の並べ替え基準をカプセル化して、最初で唯一の適切な並べ替えを行う方法が必要でした。

私はすでにSort上記のメソッドを持っていたので、keySelector パラメーターをクラスのプロパティに入れるのが最も簡単だと考えました。言語ではそれができないことがわかりましたが、今ではその理由がわかり、理解しています。

これを機能させるために私が最終的に行ったことは、Funcプロパティを実装するオブジェクトへの参照に置き換えることでしIComparer<T>た。Tこのプロパティを宣言するのに問題はありません。また、コレクション宣言でパラメーターとして渡される型ごとにそれを実装するクラスを宣言するのは簡単です。コレクション オブジェクトを割り当てた後にプロパティを初期化し、Sortメソッドを次のように書き直しました。

public void Sort() {
    if ( Comparer != null ) {
        InternalSort( Items.Skip( RowsToSkip ).OrderBy( item => item, Comparer ) );
    } else { 
        InternalSort( Items.Skip( RowsToSkip ).OrderBy( item => item ) );
    }
}

RowsToSkipintコレクションの先頭にある何行をスキップするかを指定するクラスのプロパティです。これにより、リストの先頭に「選択肢を選んでください」のようなエントリを追加し、並べ替えによって移動させないようにすることができます。

于 2013-02-05T15:28:04.567 に答える
0

これを試して:

public class SortableObservableCollection<T, TKey>:ObservableCollection<T>
{
    public Func<T,TKey> Key1 {get; set;}
}
于 2013-02-02T18:01:35.283 に答える