Error with list <T>. Contains (T) in LINQ query

I wonder why this is not working. Insight is appreciated.

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

The expected result from MyTest () is List {2, 3}. However, the compiler reports two errors in input.Contains(b) , as shown below:

  • Argument 1: cannot convert from 'int' to 'T'

  • The best overloaded method match for 'System.Collections.Generic.List.Contains (T)' has some invalid arguments

This Where () clause works fine if I don't use shared lists.

This is a simplification of my real problem, so please do not dwell on "why are you writing this?" The problem is the error and its occurrence.

Revised for (hopefully) clarity:

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

The same compiler errors are reported to input.Contains(f.Property) .

+4
source share
5 answers

Try the following:

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

The problem is that the compiler has no idea what type T is. Since T can be anything, you cannot call the method that int ( input.Contains ) expects.

0
source

input must be List<int>

and then when you call the function, if T not an int, you will know that it will always return an empty list.

a function does not make much sense when T not an int.

+2
source

Just look at this feature in isolation.

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

What if T was an object ... or a string .. nothing stopped T from these types there. If T was one of these types, the statement input.Contains(b) would not make sense.

The compiler complains because you allow types that do not make sense with instructions in the body of the method.

+1
source

also another solution

 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(); } 
+1
source

The compiler cannot guarantee that any value of <T> - any <T> , DateTime, object, whatever - will be bound to int. That is why you get your first mistake.

In some cases, you can specify the type of an object in the signature of your function:

  private static List<int> MyTest<T>(List<T> input) where T : someObject 

This will not work for your case, because int is a structure. You can work with it in many other ways (other answers provide some excellent methods), but you will have to somehow change your current strategy.

0
source

Source: https://habr.com/ru/post/1445867/


All Articles