2017-03-27 4 views
2

私はMyUserクラスに汎用識別子型を持っています。 UserManagerクラスには、GetByIdentifierメソッドがあります。このメソッドは、指定された識別子を既知のユーザー識別子と比較します。問題は、私は次のエラーを取得することです:シンプルジェネリック型compare

public MyUser<TIdentifier> 
{ 
    public TIdentifier Identifier { get; set; } 
} 

public class UserManager<TUser, TUserIdentifier> 
    where TUser : MyUser<TUserIdentifier> 
{ 
    protected List<TUser> userStore = new List<TUser>(); 
    protected TUser GetByIdentifier(TUserIdentifier identifier) 
    { 
     return userStore.FirstOrDefault(c => c?.Identifier == identifier); 
    } 
} 

私はもう、intとしてTUserIdentifierとしてstring電気ショック療法を単純型を定義することはできません以下にUserManagerの署名を変更

Operator '==' cannot be applied to operands of type 'TUserIdentifier' and 'TUserIdentifier'

public class UserManager<TUser, TUserIdentifier> 
    where TUser : MyUser<TUserIdentifier> 
    where TUserIdentifier : class 

回避策はIntegerStringなどのクラスを使用することです。


私がやってみましたもう一つは、以下の署名であるが、それは

public class UserManager<TUser, TUserIdentifier> 
    where TUser : MyUser<TUserIdentifier> 
    where TUserIdentifier : IComparable 

を動作しませんでした私はIntegerStringなどのクラスのために行くか、別の方法がありますでしょうか?

+0

http://stackoverflow.com/questions/390900/cant-operator-be-applied-to-generic-types-in-c – CodeCaster

+0

@CodeCasterこの投稿を理解すると、基本的には参照型コンパイラがその型が同等であることを知ることができます(演算子は適用できます)。したがって、int、stringなどの参照型実装を使用する必要があります。そうですか? – NtFreX

+0

さらに、TUserIdentifier:オブジェクトのどこにでも使用できます。これは私が思うように動作するはずです。 – Sebi

答えて

4

ここでの問題は、誤って2つの値の型の間で参照の等価チェックを実行していないことをコンパイラが確信できないことです。 ReferenceEquals(1, 1)いつもfalseとなります。参照の平等は値型では意味をなさない!

ジェネリック型は参照型(class制約)に制約されていないため、コンパイラは==演算子を単に使用しません。なぜなら、そのデフォルト実装は正確に参照の等価性であるからです。

この問題を回避するには、仮想Equalsメソッドを使用します。

+0

ありがとうthats正確に何を私が探していた – NtFreX

+2

@ Dr.Fre不要なボクシングを避けるために、可能であれば、 'TUserIdentifier'を' IEquatable 'に制限することを検討してください。 – InBetween