2017-02-15 9 views
1

Я искал Google, но не смог найти удовлетворительных ответов. Я в основном пытаюсь получить этот код на работу:C# convert System.Func <Tderived, bool> to 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 типа, используйте два метода. –

+0

Если вы выполняете проверку типов на универсальном типе, вы почти всегда делаете плохой выбор дизайна. – juharr

+0

Я бы сказал, что это имеет какое-то отношение к дисперсии типа - компилятор не разрешает неявный приведение к родительскому типу. – gobes

ответ

8

В принципе, вам просто нужно отличить - правила языка не позволяют компилятору принимать во внимание заявление if, когда он думает о соответствующих типах. Обратите внимание, что вы также нужно вызвать ToList<Entry>(), указав тип аргумента, чтобы избежать получать List<WordEntry> или List<CharacterEntry>:

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; 
} 

я бы предположить, что вместо того, чтобы это родовое, хотя, вы можете просто два различных вместо этого. Не похоже, что действительно - общий метод, учитывая, что он работает только с двумя очень специфическими типами.

+0

Спасибо, что ответили. Однако я попробовал лить func раньше.Но часть: (Func ) предикат Выдает ошибку: Error \t \t CS0030 Невозможно преобразовать тип 'System.Func ' до 'System.Func ' – user1370286

+0

@ user1370286: Ах, вам может потребоваться бросок для 'object'. Добавлю, что в. –

+0

@ user1370286: На самом деле, нет, мой код компилируется для меня отлично. Это действительно должно быть хорошо - создаст сущность, чтобы показать ... –

4

Вашего метода SelectWhere делает разные вещи в зависимости от типа аргумента - так почему бы не просто использовать методы перегрузки

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

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

Затем вы можете использовать этот метод без литья и «ужасного» 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 
0

Из ошибок, которые вы показали, я думаю, что ваш предикат имеет неправильное объявление.

где положение на оба ваших базы данных объектов ожидает Func<T, int, bool>, обратите внимание, второй аргумент, который является INT, поэтому изменить способ расширения, как это должно быть прогресс в правильном направлении

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

NOTE : Вы объявили общий метод, в котором ваш код зависит от типа общего типа, это делает код каким-то образом не столь общим, проверьте @Fabio ответ, я думаю, что он имеет смысл создавать отдельные методы расширения.

Смежные вопросы