无法将lambda表达式转换为委托类型';System.Func<;T、 TKey>';
本文关键字:System Func gt TKey lt 类型 lambda 表达式 转换 | 更新日期: 2023-09-27 17:58:29
我正在为min-heap编写一个泛型类,我希望能够在TKey
和T
上进行堆。
interface IHeap<T, TKey>
where TKey : IComparable<TKey>
{
void Insert(T x);
T Delete();
T Top();
}
public class MinHeap<T, TKey> : IHeap<T, TKey>
where TKey : IComparable<TKey>
{
public MinHeap(int capacity)
: this(capacity, x => x) // <---- compilation error here
{ }
public MinHeap(int capacity, Func<T, TKey> keySelector)
: this(capacity, keySelector, Comparer<TKey>.Default)
{ }
public MinHeap(int capacity, Func<T, TKey> keySelector, IComparer<TKey> comparer)
{
// ...
}
// ...
}
我得到了x => x
:的这些编译错误
Cannot convert lambda expression to delegate type 'System.Func<T,TKey>' because some of the return types in the block are not implicitly convertible to the delegate return type.
Cannot implicitly convert type 'T' to 'TKey'
我如何做到这一点,只上一节课?
更新:
我想做两件事:
// 1
var minheap = new MinHeap<Person, int>(10, x => x.Age);
// 2
var minheap = new MinHeap<int>(10);
// instead of
var minheap = new MinHeap<int, int>(10, x => x);
MinHeap<T,TKey>
可以用任何与约束匹配的泛型类型参数实例化。
这意味着,例如,您可以有一个MinHeap<string,int>
。在这种情况下,您将尝试将lambda x => x
分配给Func<string,int>
,但这不会起作用,因为它是Func<string,string>
。
我不认为有一种明智的方法可以实现你想要的,因为没有一种好的"默认"方法可以将一个任意类型转换为另一个任意的类型,这正是你所需要的。
您可以删除此构造函数并添加一个静态构造函数,该构造函数可用于T
和TKey
为同一类型的情况:
public static class MinHeap
{
public static MinHeap<T,T> Create<T>(int capacity) where T : IComparable<T>
{
return new MinHeap<T,T>(capacity, x => x);
}
}
但是,如果这还不足以满足您的需求,那么只需删除构造函数,并接受人们将不得不自己传递lambda。
x => x
是一个Func<T, T>
,而不是其他构造函数所要求的Func<T, TKey>
。
您需要有一个默认的选择器,或者更好的是,我会禁止该构造函数,并强制用户在实例化类时提供一个键选择器。
我将把我的答案添加为
- 尽管我付出了很多,但很少有人不明白我想做什么一个例子
- 没有人提到这个答案
我从MinHeap<T, TKey>
中删除了构造函数。我将另一个类定义如下。
public class MinHeap<T> : MinHeap<T, T>
where T : IComparable<T>
{
public MinHeap(int capacity)
: this(capacity, Comparer<T>.Default)
{ }
public MinHeap(int capacity, IComparer<T> comparer)
: base(capacity, x => x, comparer)
{ }
}