2010-04-07 14 views
7

Rzućmy następujący przykład:nazw scoped aliasy typów generycznych w języku 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 
} 

Kompilator mówi:

Argumenty typu dla metody „System.Linq.Enumerable.Select (Systemu .Collections.Generic.IEnumerable, System.Func) "nie można wywnioskować z użycia za pomocą . Spróbuj jednoznacznie określić argumenty typu .

To dlatego, że nie można przekonwertować Bar na Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

Byłoby świetnie, gdybym mógł utworzyć aliasy typu o typie przestrzeni nazw dla typów ogólnych w języku C#. Wtedy zdefiniowałbym nie jako delegata, ale raczej zdefiniowałbym go jako alias o przestrzeni nazw o nazwie Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

public alias Bar = Func<IList<X>, int, IDictionary<Y, IList<Z>>>; 

Mogłabym również zdefiniować alias o zasięgu nazw, np. IDictionary<Y, IList<Z>>.

A jeśli użyje się go odpowiednio :), sprawi, że kod będzie bardziej czytelny. Teraz muszę wpisać typy ogólne i prawdziwy kod nie jest dobrze czytelny :(

Czy znalazłeś ten sam problem :)? Czy jest jakiś dobry powód, dla którego nie jest w C# 3.0? Lub nie ma dobrego powodu, to tylko kwestia pieniędzy i/lub czasu?

EDYCJA: Wiem, że mogę używać using, ale to nie jest obszar nazw o zasięgu - nie jest to tak wygodne dla mojego przypadku.

EDIT2: Zobacz, comment by Joren, gdzie sugeruje, że pisanie strukturalne może również rozwiązać problem.

+0

Nie jestem pewien, jaki jest problem z 'using' - czy nie definiuje nowego typu, ale czy nie tego właśnie chcesz? –

+0

Tak jak napisałem, nie jest to obszar nazw, ale zakres plików. Potrzebuję użyć aliasu dla plików i złożeń cs. –

Odpowiedz

8

Jesteś pecha; dyrektywa use wpływa tylko na bieżący plik. Nie ma mechanizmu aliasowania typu całej przestrzeni nazw.

Jest to dość często żądana funkcja, która jest dla niego odpowiednia. Ale jest to również funkcja "miło mieć", w przeciwieństwie do takiej, która naprawdę dodaje dużo języka do reprezentacji, co wskazuje na to. Byłoby miło, ale nie jest tak wysoko na liście priorytetów.

+1

Jeśli się nie mylę, pisanie strukturalne na delegatach może również umożliwić kompilatorowi radzenie sobie z tą konkretną sytuacją, aczkolwiek w bardzo różny sposób.Czy istnieje jakaś uzasadniona szansa, że ​​kiedyś zostanie wdrożone wsparcie typowania strukturalnego dla takich osób jak delegaci? – Joren

+0

@Joren: Tak, to rozwiąże ten problem. Myślę, że większość ludzi zdaje sobie teraz sprawę z tego, że od początku dobrze byłoby mieć typowanie strukturalne od delegatów, ale ten statek płynął. Byłaby to naprawdę duża zmiana, aby zmienić ją teraz. To powiedziawszy, istnieje ponowne zainteresowanie typowaniem strukturalnym, więc nie chciałbym oświadczać, że nie ma * nie * szansy na to. –

0

Jeśli zrobisz ...

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

może dowiedzieć typy dla Ciebie bez konieczności określania ich wyraźnie.

(Prawdą jest to bardziej obejście niż rozwiązanie)

+1

Tak, wiem :) Nie odpowiada na moje pytanie, ale dzięki :) –

Powiązane problemy