2017-02-15 4 views
1

私はグーグルではありましたが、満足のいく回答は見つかりませんでした。このサンプルでC#System.Func <Tderived、bool>をSystem/Funcに変換します。<Tbase, bool>

public List<WordEntry> WordDataBase = new List<WordEntry>(); 
public List<CharacterEntry> CharacterDataBase = new List<CharacterEntry>(); 

public List<Entry> SelectWhere<T>(System.Func<T, bool> predicate) where T : Entry 
{ 
    if (typeof(T) == typeof(WordEntry)) 
     return WordDataBase.Where(predicate); 
    else if (typeof(T) == typeof(CharacterEntry)) 
     return CharacterDataBase.Where(predicate); 
    else 
     return null; 
} 

を、両方WordEntryとCharacterEntryは、エントリから派生している:私は基本的に仕事にこのコードを取得しようとしています。私は、コンパイラのエラーを取得:

Error CS1503 Argument 2: cannot convert from 'System.Func<T, bool>' to 'System.Func<WordEntry, int, bool>' 

Error CS1503 Argument 2: cannot convert from 'System.Func<T, bool>' to 'System.Func<CharacterEntry, int, bool>' 

うまくいけば、あなたはこれで私を助けることができます。事前に感謝します

+1

これは方法としてはやや意味がないと思います。 2つのタイプがある場合は、2つの方法があります。 –

+0

ジェネリック型の型チェックを行っている場合は、ほとんどの場合、デザインの選択肢が貧弱です。 – juharr

+0

私はそれが型の分散と関係があると言います - コンパイラは親の型への暗黙のキャストを許可しません。 – gobes

答えて

8

基本的には、キャストする必要があります - 言語ルールは、関係するタイプについて考えるとき、コンパイラがifステートメントを考慮に入れないようにします。あなただけの別の2を持っている場合があります、しかし、このジェネリックを

public List<Entry> SelectWhere<T>(Func<T, bool> predicate) where T : Entry 
{ 
    if (typeof(T) == typeof(WordEntry)) 
     return WordDataBase 
      .Where((Func<WordEntry, bool>) predicate) 
      .ToList<Entry>(); 
    else if (typeof(T) == typeof(CharacterEntry)) 
     return CharacterDataBase 
      .Where((Func<CharacterEntry, bool>) predicate) 
      .ToList<Entry>(); 
    else 
     return null; 
} 

が、私はそれをお勧めしたいのではなく作る:あなたはList<WordEntry>またはList<CharacterEntry>避けるために型引数を指定して、ToList<Entry>()を呼び出す必要があることに注意してください代わりにメソッド。 のように実際にはの2つの非常に特殊なタイプでしか動作しないという点で、一般的な方法とは感じられません。引数のタイプに基づいて異なることを行いSelectWhere

+0

お返事ありがとうございます。しかし、私は前にfuncをキャストしようとしました。しかし一部: (funcは)述語 がエラー与える: エラー\t CS0030を\t変換できません型 'System.Func ' – user1370286

+0

user1370286 @に 'System.Func ':ああ、最初に 'object'へのキャストが必要な場合があります。 –

+0

@ user1370286:実際は、いいえ、私のコードはうまくコンパイルされます。それは本当にうまくいくはずです - 表示する要点を作成します。 –

4

あなたの方法 - なぜちょうどその後、あなたは鋳造とせずに「恐ろしい」if...else

Func<WordEntry, bool> isValid = word => word.SomeProperty > 0; 
var filteredWords = SelectWhere(isValid); // WordDataBase will be used 

Func<CharacterEntry, bool> IsValid = character => character.SomeProperty != null; 
var filteredCharacters = SelectWhere(IsValid); //CharacterDataBase will be used 
をこれらのメソッドを使用することができ、過負荷方法

public List<WordEntry> SelectWhere(Func<WordEntry, bool> predicate) 
{ 
    return WordDataBase.Where(predicate); 
} 

public List<CharacterEntry> SelectWhere(Func<CharacterEntry, bool> predicate) 
{ 
    return CharacterDataBase.Where(predicate); 
} 

を使用しません

0

あなたが示したエラーから、私はあなたの述語が間違った宣言をしていると思います。

あなたデータベースオブジェクトの両方の句はFunc<T, int, bool>見込んザ・ので、このようなあなたの拡張メソッドを変更して右方向に進行

public List<Entry> SelectWhere<T>(Func<T, int, bool> predicate) where T : Entry 

NOTEする必要があり、int型である第二引数に注意してください。 :あなたはコードがジェネリック型に依存するジェネリックメソッドを宣言しました。これは何とかジェネリックではないコードになります@Fabio答えをチェックしてください。

関連する問題