2016-07-22 151 views
0

我正在为最小堆编写泛型类,我希望能够在TKey以及T上堆积。无法将lambda表达式转换为委托类型'System.Func <T,TKey>'

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); 
+0

编译器错误很清楚为什么代码无效。你的问题是不清楚你为什么认为这样的代码应该工作。泛型的要点是提供编译时类型安全性,但考虑到当前的声明,不可能在编译时确保该表达式的类型安全。请更好地解释你的想法。 –

+0

我想在个人财产('TKey')的Person.Age上堆人Person []。我也想在int []('T')上堆砌。 – hIpPy

+0

想做点事不是一个解释。我希望我的C#编译器每次编译我的程序时都会给我一个巧克力薄荷,但是我没有任何问题想问我如何才能做到这一点。据了解,这是不可能的。同样,你要求编译器做一些根本不可能的事情。请解释_为什么你认为这应该是可能的。 Ben的回答最接近我认为在这方面会有用的东西,但我担心这并不能真正解决您的误解。如果不明白误解会更好,我们无法做到这一点。 –

回答

2

MinHeap<T,TKey>可以用任何匹配约束的泛型类型参数实例化。

这意味着例如,您可以有一个MinHeap<string,int>。在这种情况下,您会尝试将lambda x => x分配给Func<string,int>,这不起作用,因为它是Func<string,string>

我不认为有一个明智的方法来实现你想要的,因为没有一个好的候选方法来将一个任意类型转换为另一个任意类型,这是你需要的。


你可以做的是消除这种构造,并添加其可以用于情况下,当TTKey是同一类型的静态构造函数:

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自己。

+0

感谢您的示例和解决方法。我选择了传递lambda而不是静态辅助方法。 – hIpPy

2

x => xFunc<T, T>,不是Func<T, TKey>在你的其他的构造要求。

你需要有一个默认的选择器,或者更好的是我会禁止该构造函数,并强制用户在实例化类时提供一个键选择器。

-1

我加入我的答案

  1. 很少有人不明白我想要什么,尽管给 为例做。
  2. 没有人提到过这个答案。

我从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) 
    { } 
} 
+0

为什么-1?请解释。 – hIpPy

+0

@ peter-duniho,你是我的答案吗?如果是这样,为什么? – hIpPy

相关问题