2016-07-22 7 views
0

Ich schreibe eine generische Klasse für Min-Heap, wo ich auf TKey sowie T Heap-fähig sein möchte.Kann Lambda-Ausdruck nicht in Delegate-Typ konvertieren '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) 
    { 
     // ... 
    } 
    // ... 
} 

ich diese Kompilierungsfehlern für 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' 

Wie erreiche ich dieses und haben nur eine Klasse?

Update:

Ich möchte in der Lage sein, zwei Dinge zu tun:

// 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

Der Compilerfehler ist klar, warum der Code ungültig ist. Ihre Frage ist _nicht_ klar, warum Sie denken, dass ein solcher Code funktionieren sollte. Der Sinn von Generika besteht darin, die Typsicherheit für die Kompilierung zu gewährleisten, aber angesichts Ihrer aktuellen Deklarationen ist es nicht möglich, die Typensicherheit zum Zeitpunkt der Kompilierung für diesen Ausdruck sicherzustellen. Bitte erkläre dein Denken besser. –

+0

Ich möchte Person [] auf Person.Age, die Eigenschaft einer Person ('TKey'), häufen. Ich würde auch gern auf int [] ('T') häufen. – hIpPy

+0

Etwas tun zu wollen, ist keine Erklärung. Ich möchte, dass mein C# -Compiler mir jedes Mal eine Schokoladenminze aushändigt, wenn ich mein Programm kompiliere, aber es hat keinen Sinn, mich zu fragen, wie ich es dazu bringen kann. Es ist klar, dass das nicht möglich ist. Ebenso bitten Sie den Compiler, etwas zu tun, was schlicht unmöglich ist. Bitte erklären Sie, warum Sie es für möglich halten. Bens Antwort kommt dem am nächsten, was meiner Meinung nach in diesem Zusammenhang nützlich sein könnte, aber ich befürchte, dass es nicht wirklich auf dein Missverständnis eingeht. Das können wir nicht tun, ohne das Missverständnis besser zu verstehen. –

Antwort

2

MinHeap<T,TKey> können mit generischen Typparametern instanziiert werden, die den Beschränkungen entsprechen.

Das bedeutet zum Beispiel, Sie könnten eine MinHeap<string,int> haben. In diesem Fall würden Sie versuchen, Lambda x => x zu einer Func<string,int> zuweisen, die nicht funktionieren würde, da es eine Func<string,string> ist.

Ich glaube nicht, dass es eine vernünftige Möglichkeit gibt, das zu erreichen, was Sie wollen, da es keinen guten Kandidaten für eine "Standard" -Möglichkeit gibt, einen beliebigen Typ in einen anderen beliebigen Typ zu konvertieren.


Was Sie tun können, ist diesen Konstruktor zu entfernen und einen statischen Konstruktor hinzufügen, die für die Fälle verwendet werden könnten, wenn die T und TKey vom gleichen Typ sind:

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

Aber wenn dies nicht der Fall ist Genug für deine Bedürfnisse, dann entferne einfach den Konstruktor und akzeptiere, dass Leute mit der Weitergabe eines Lambdas an sich selbst fertig werden müssen.

+0

Vielen Dank für das Beispiel und einen Workaround. Ich entschied mich dafür, das Lambda anstelle einer statischen Hilfsmethode zu übergeben. – hIpPy

2

x => x ist ein Func<T, T>, kein Func<T, TKey> wie in der anderen Konstruktor erforderlich.

Sie müssen einen Standardselektor haben, oder besser noch, ich würde diesen Konstruktor ablehnen und den Benutzer zwingen, einen Schlüsselselektor bereitzustellen, wenn die Klasse instanziiert wird.

-1

Ich füge meine Antwort als

  1. Nur wenige Menschen nicht verstehen, was ich trotz geben ein Beispiel tun wollte.
  2. Niemand erwähnte diese Antwort.

Ich entfernte den Konstruktor von MinHeap<T, TKey>. Ich habe eine andere Klasse wie folgt definiert.

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

warum -1? bitte erkläre. – hIpPy

+0

@ Peter-Duniho, hast du -1 meine Antwort? Wenn ja warum? – hIpPy

Verwandte Themen