2016-07-22 152 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

相關問題