2016-05-12 16 views
0

私は以下のコードスニペットの汎用メソッドを記述しようとしましたが、OrderBy節でエラーが出ますか?理由を教えてください。一般的な方法でエラーが発生する

var cache = RedisConnectorHelper.Connection.GetDatabase(); 
var values = JsonConvert.DeserializeObject<List<StateListDto>>(cache.StringGet(AppConsts.States)); 
if (values != null) return new ListResultOutput<StateListDto>(values.OrderBy(o => o.Name).ToList()); 

ジェネリックメソッド:

public ListResultOutput<T> GetCache<T>(string cacheKey) 
    { 
     var cache = RedisConnectorHelper.Connection.GetDatabase(); 
     var values = JsonConvert.DeserializeObject<List<T>>(cache.StringGet(cacheKey)); 
     return values != null ? new ListResultOutput<T>(values.ToList().OrderBy(o=>o.Name)) : null; 
    } 

コール:

var values = GetCache<StateListDto>(AppConsts.States); 

StateListDto.cs

public class StateListDto 
    { 
     public string Code { get; set; } 
     public string Name { get; set; } 
    } 

それは、このエラーを与える:(フルサイズの画像を表示するにはクリック)

enter image description here

+4

「一般的な」コードは、 'T'は' Name'プロパティを持っています。あなたは 'where T:StateListDto'制約を追加できましたが、それが_correct_であるかどうかは明らかではありません。 –

+0

@DStanleyどうすればこの問題を解決できますか?何かアドバイス ? – Sampath

+0

これはどのように一般的ですか?どんなタイプがサポートされるはずですか? – Amit

答えて

1

あなたは、このようなパラメータとしてによって注文したいの道を送信することができます

public ListResultOutput<T> GetCache<T>(string cacheKey, Func<T,object> selector) 
{ 
    var cache = RedisConnectorHelper.Connection.GetDatabase(); 
    var values = JsonConvert.DeserializeObject<List<T>>(cache.StringGet(cacheKey)); 
    return values != null ? new ListResultOutput<T>(values.OrderBy(selector).ToList()) : null; 
} 

コール:あなたのクラスを強制しない。このように

GetCache<StateListDto>("yourKey", i=>i.Name); 

何でも実装することができます。コード内の他のパラメータで注文することもできます。

+0

あなたはこのメソッドを呼び出す方法を教えてくれますか? – Sampath

+0

GetCache ( "yourKey"、i => i.Name); – greenberet

+0

ありがとうございます。これが私の必要なものです。私のシナリオでは完璧な解決策です。既存のコード変更を行う必要はありません。チェイサー: – Sampath

2

あなただけStateListDto私は希望以上のためにこれを使用することを期待している場合Nameというプロパティを持つインターフェイスまたは基本クラスを作成することをお勧めします。

ような何か:

​​

、その後、あなたはにあなたの方法を変更することができます。そして、彼らのために共通のインターフェースを作成

public ListResultOutput<T> GetCache<T>(string cacheKey) where T: IDto 
{ 
    var cache = RedisConnectorHelper.Connection.GetDatabase(); 
    var values = JsonConvert.DeserializeObject<List<T>>(cache.StringGet(cacheKey)); 
    return values != null ? new ListResultOutput<T>(values.ToList().OrderBy(o=>o.Name)) : null; 
} 
+0

私の 'dtos'の全てにこの' interface'を実装する必要がありますか? – Sampath

+0

@Sampathこのメソッドを使用したいすべての 'dtos'が表示されます。あなたがそれをすべて必要としないなら、多分Davidsの答えのような 'INamed'のようなインターフェースの良い名前 – Bijington

1

But all are having Name property.

、このような何か:

public interface INamed 
{ 
    string Name { get; } 
} 

あなたのすべてのモデルはt帽子のプロパティは、そのインターフェイスを実装することができます。

public class StateListDto : INamed 

次にあなたがジェネリックメソッドの型制約としてそのインターフェイスを使用することができます。コンパイラはTの種類がありますことを保証することができます

public ListResultOutput<T> GetCache<T>(string cacheKey) where T: INamed 

その方法Nameプロパティ。

これを達成するために、基本クラス、具体的または要約を使用することもできます。個人的には、継承を使用する特定の理由がない限り、継承よりもインターフェイスを使用する方が好きです。

関連する問題