想知道为什么这不起作用。洞察力很高兴。
static void Main(string[] args)
{
List<int> foo = new List<int> { 1, 2, 3 };
var myResult = MyTest<int>(foo);
}
private static List<int> MyTest<T>(List<T> input)
{
List<int> bar = new List<int> { 2, 3, 4 };
return bar.Where(b => input.Contains(b)).ToList();
}
MyTest()的预期输出是List {2,3}。但是,编译器会在input.Contains(b)
上报告两个错误,如下所示:
参数1:无法从'int'转换为'T'
'System.Collections.Generic.List.Contains(T)'的最佳重载方法匹配有一些无效的参数
如果我不使用通用列表,这个Where()子句可以正常工作。
这是我现实世界问题的简化,所以请不要陷入“为什么要写这个?”问题在于错误及其发生的原因。
修订(希望)清晰度:
namespace SandBox
{
class Foo
{
public int FooInt { get; set; }
public string FooString { get; set; }
}
class Program
{
private static List<Foo> fooList = new List<Foo> {
new Foo() {FooInt = 1, FooString = "A"},
new Foo() {FooInt = 2, FooString = "B"},
new Foo() {FooInt = 3, FooString = "C"}
};
static void Main(string[] args)
{
List<int> myIntList = new List<int> { 1, 2 };
var myFirstResult = GetFoos<int>(myIntList);
List<string> myStringList = new List<string> { "A", "B" };
var mySecondResult = GetFoos<string>(myStringList);
}
/// <summary>
/// Return a list of Foo objects that match the input parameter list
/// </summary>
private static List<Foo> GetFoos<T>(List<T> input)
{
//***
// Imagine lots of code here that I don't want to duplicate in
// an overload of GetFoos()
//***
if (input is List<int>)
{
//Use this statement if a list of integer values was passed in
return fooList.Where(f => input.Contains(f.FooInt));
}
else if (input is List<string>)
{
//Use this statement if a list of string values was passed in
return fooList.Where(f => input.Contains(f.FooString));
}
else
return null;
}
}
}
input.Contains(f.Property)
报告了相同的编译器错误。
答案 0 :(得分:2)
input
应为List<int>
然后,每当你调用该函数时,如果T
不是int,你就会知道它总会返回一个空列表。
当T
不是int时,该函数没有多大意义。
答案 1 :(得分:1)
单独看看这个功能。
private static List<int> MyTest<T>(List<T> input)
{
List<int> bar = new List<int> { 2, 3, 4 };
return bar.Where(b => input.Contains(b)).ToList();
}
如果T是对象...或者字符串怎么办?没有什么可以阻止T成为那些类型。如果T是这些类型中的一种,则语句input.Contains(b)
将没有意义。
编译器抱怨,因为你允许使用方法体中的语句没有意义的类型。
答案 2 :(得分:1)
另一个解决方案
static void MainT(string[] args)
{
List<int> foo = new List<int> { 1, 2, 3 };
var myResult = MyTest<int>(foo);
}
private static List<int> MyTest<T>(List<T> input) where T : IEquatable<int>
{
List<int> bar = new List<int> { 2, 3, 4 };
return bar.Where(b => input.Any(i => i.Equals(b))).ToList();
}
答案 3 :(得分:0)
试试这个:
static void Main(string[] args)
{
List<int> foo = new List<int> { 1, 2, 3 };
var myResult = MyTest<int>(foo);
}
private static List<int> MyTest<T>(List<T> input)
{
List<int> bar = new List<int> { 2, 3, 4 };
return bar.Where(b => input.OfType<int>().Contains(b)).ToList();
}
问题在于编译器不知道T是什么类型。因为T可以是任何你不能调用期望int(input.Contains
)。
答案 4 :(得分:0)
编译器不能保证任何&lt; T&gt; - 任何&lt; T&gt; ,DateTime,对象,等等 - 都可以转换为int。这就是你收到第一个错误的原因。
在某些情况下,您可以在函数的签名中指定一种对象:
private static List<int> MyTest<T>(List<T> input) where T : someObject
这对你的情况不起作用,因为int是一个结构。您可以通过许多其他方式使用它(其他答案给出了一些很好的方法),但您必须以某种方式调整当前的策略。