2010-04-07 5 views
7

Werfen sich ein folgendes Beispiel hat:Namespace scoped Aliase für generische Typen in C#

public class X { } 
public class Y { } 
public class Z { } 

public delegate IDictionary<Y, IList<Z>> Bar(IList<X> x, int i); 

public interface IFoo 
{ 
    // ... 
    Bar Bar { get; } 
} 

public class Foo : IFoo 
{ 
    // ... 
    public Bar Bar 
    { 
     get 
     { 
      return null; //... 
     } 
    } 
} 

void Main() 
{ 
    IFoo foo; //= ... 
    IEnumerable<IList<X>> source; //= ... 
    var results = source.Select(foo.Bar); // <- compile error here 
} 

Der Compiler sagt:

Die Art Argumente für die Methode ‚System.Linq.Enumerable.Select (System .Collections.Generic.IEnumerable, System.Func) 'kann nicht aus der Verwendung abgeleitet werden. Versuchen Sie , indem Sie die Typargumente explizit angeben.

Es ist, weil es Bar zu Func<IList<X>, int, IDictionary<Y, IList<Z>>> nicht umwandeln kann.

Es wäre toll, wenn ich Typ-Namespace-Typ-Aliase für generische Typen in C# erstellen könnte. Dann würde ich Bar nicht als ein Delegat definieren, aber ich würde es eher als einen Namespace definierten Alias ​​für Func<IList<X>, int, IDictionary<Y, IList<Z>>> definieren.

Ich könnte dann auch definieren Namespace Bereich Alias ​​für z. IDictionary<Y, IList<Z>>.

Und wenn geeignet verwendet :), wird es den Code lesbarer machen. Nun, ich muss die generischen Typen inline und der echte Code ist nicht gut lesbar :(

Haben Sie die gleichen Probleme :)? Gibt es einen guten Grund, warum es nicht in C# 3.0 ist? Oder es gibt keinen guten Grund, es ist nur eine Frage von Geld und/oder Zeit?

EDIT: Ich weiß, dass ich using verwenden kann, aber es ist nicht Namespace-Bereich - nicht so bequem für meinen Fall.

EDIT2: Siehe comment by Joren, wo er darauf hinweist, dass strukturelle Typisierung auch das Problem lösen könnte.

+0

Ich bin mir nicht sicher, was das Problem mit 'using' ist - gewährt es nicht einen neuen Typ zu definieren, aber ist das nicht das, was Sie wollen? –

+0

Wie ich geschrieben habe, ist es nicht Namespace, sondern Dateibereich. Ich muss den Alias ​​über CS-Dateien und Assemblys verwenden. –

Antwort

8

Du bist kein Glück; Die using-Direktive betrifft nur die aktuelle Datei. Es gibt keinen Aliase-Mechanismus vom Typ Namespace-weit.

Dies ist eine ziemlich häufig angeforderte Funktion, die Punkte dafür ist. Aber es ist auch ein "nice to have" -Komfort-Feature im Gegensatz zu einem, das der Sprache wirklich viel Repräsentationskraft verleiht, was dagegen spricht. Es wäre nett zu tun, aber es ist nicht wirklich hoch auf der Prioritätenliste.

+1

Wenn ich mich nicht irre, kann strukturelle Typisierung auf Delegaten auch dem Compiler ermöglichen, sich mit dieser spezifischen Situation zu befassen, wenn auch auf eine ganz andere Art und Weise.Gibt es eine vernünftige Chance, dass die Unterstützung für strukturelles Schreiben für Dinge wie Delegierte irgendwann implementiert wird? – Joren

+0

@Joren: Ja, das würde dieses Problem lösen. Ich denke, die meisten Leute erkennen jetzt, dass es besser gewesen wäre, von Anfang an strukturelle Eingaben über Delegierte zu machen, aber dieses Schiff ist gesegelt. Es wäre eine ziemlich große, bahnbrechende Veränderung, es jetzt zu ändern. Allerdings gibt es ein erneutes Interesse an struktureller Typisierung, daher möchte ich nicht die Aussage machen, dass es keine Chance dafür gibt. –

0

Wenn Sie das tun ...

var results = source.Select((x, i) => foo.Bar(x, i)); 

kann die Typen für Sie herausfinden, ohne dass sie explizit angeben zu müssen.

(Zugegebenermaßen ist dies eher eine Behelfslösung als eine Lösung)

+1

Ja, ich weiß :) Es beantwortet meine Frage nicht, aber danke :) –