2017-02-15 44 views
1

我google了,但无法找到满意的答案。我基本上试图让这个代码工作:C#转换System.Func <Tderived,布尔>到系统/功能<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都从Entry派生。我得到的编译器错误:

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

我认为这是一种毫无意义的方法。如果你有两种类型,那么有两种方法。 –

+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键)谓词 给出了错误: 错误\t CS0030 \t无法将类型 'System.Func ' 到 'System.Func ' – user1370286

+0

@ user1370286:啊,你可能需要首先投射“对象”。将添加在。 –

+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 

注意进度:你已经声明了泛型方法,其中你的代码依赖于泛型类型,这使得代码在某种程度上不是那么通用,请检查@Fabio答案,我认为他有创建单独扩展方法的意义。

相关问题