Псевдонимы пространства имен для общих типов в С#

Пусть имеет следующий пример:

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
}

Компилятор говорит:

Аргументы типа для метода "System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func) 'не может быть выведенным из использования. Пытаться задание аргументов типа в явном виде.

Это потому, что он не может преобразовать Bar в Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

Было бы здорово, если бы я мог создавать псевдонимы типа пространства имен типа для общих типов в С#. Тогда я бы определил Bar не как делегат, но я бы определил его как псевдоним с пространством имен для Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

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

Затем я мог бы также определить псевдоним с пространственным разделением имен, например. IDictionary<Y, IList<Z>>.

И если используется соответствующим образом:), это сделает код более читаемым. Теперь я должен встраивать общие типы, а реальный код плохо читается: (

Есть ли у вас такая же проблема:)? Есть ли веская причина, почему это не в С# 3.0? Или нет веской причины, это просто вопрос денег и/или времени?

EDIT: Я знаю, что я могу использовать using, но это не пространство имен в области - не очень удобно для моего случая.

EDIT2: см. комментарий Joren, где он предлагает, чтобы структурная типизация также могла решить проблему.

Ответ 1

Вам не повезло; директива using влияет только на текущий файл. Механизм псевдонимов не существует.

Это довольно часто запрашиваемая функция, которая является точками для нее. Но это также "приятная иметь" удобная функция, в отличие от той, которая действительно добавляет много репрезентативной власти на язык, что указывает на него. Было бы неплохо сделать это, но в списке приоритетов он не очень высок.

Ответ 2

Если вы это сделаете...

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

он может определить типы для вас, не указывая их явно.

(По общему признанию, это скорее работа, чем решение)