Reputation: 3283
I'm currently experimenting with extension methods. My goal is a extension method for List which finds the first element that fits the given element in a collection, after a specified index.
public static class Extensions
{
public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item) where T : class where T : struct
{
return list.Skip<T>(index).Where<T>(result => result == item).First<T>();
}
}
so this works for class objects as T.
I also tried:
public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item) where T : class
where T : struct
{
return list.Skip<T>(index).Where<T>(result => result == item).First<T>();
}
I'm very new in the generic stuff an T so how can i define my where clause to accept also List<int>
?
regards Mark
Upvotes: 1
Views: 1962
Reputation: 4907
public static class Extensions
{
public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item)
where T :IComparable
{
return list.Skip<T>(index).Where<T>(result => result.CompareTo(item)==0).First<T>();
}
}
Upvotes: 1
Reputation: 91598
int is not a class. int will be boxed into a struct (Int32).
You'd have to remove the clause:
where T : class
Or use Int32?
instead.
Update:
Int32?
will most likely not work, since technically it will still be a struct:
public struct Nullable<T> where T : struct
Your best bet is to remove the class constraint if you want to use structs here.
Upvotes: 6
Reputation: 1500245
Your extension method in invalid in terms of its constraints:
public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item)
where T : class where T : struct
(The where T : struct
constraint is scrolled all the way over to the right on your question.)
You can't specify two constraint clauses for the same type parameter like this. You can specify one constraint clause with multiple constraints (e.g. where T : class, IDisposable
), but it can't include both the class
and struct
constraints.
If your extension method really only has one constraint and that constraint is where T : class
, then that explains why it's not valid for List<int>
- because int
doesn't satisfy the reference type constraint.
Frankly your method would be better off written like this:
public static T FindFirstAfterIndex<T>(this IEnumerable<T> list,
int index, T item)
{
return FindFirstAfterIndex(list, index, item, EqualityComparer<T>.Default);
}
public static T FindFirstAfterIndex<T>(this IEnumerable<T> list,
int index, T item,
IEqualityComparer<T> comparer)
{
return list.Skip(index)
.Where(result => comparer.Equals(result, item))
.First();
}
Now it will work for any list, and will use the default equality semantics of T
(which will make it work more conventionally for List<string>
for example) and also allow you to supply a custom equality comparer when you want to.
Upvotes: 9
Reputation: 160862
Just drop the class
constraint:
public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item)
{
}
Upvotes: 6