2010-04-07 4 views
7

Давайте следующий пример:пространство имен области видимости псевдонимы для универсальных типов в 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 
} 

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

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

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

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

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

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

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

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

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

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

+0

Я не уверен, что проблема с 'использованием' - предоставлена ​​она не определяет новый тип, но не то, что вы хотите? –

+0

Как я уже писал, это пространство имен не ограничено, а скорее скопировано в область. Мне нужно использовать псевдоним через cs-файлы и сборки. –

ответ

8

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

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

+1

Если я не ошибаюсь, структурная типизация на делегатах также может позволить компилятору справиться с этой конкретной ситуацией, хотя и совсем по-другому.Есть ли какой-то разумный шанс, что поддержка структурного ввода для таких вещей, как делегаты, когда-нибудь будет реализована? – Joren

+0

@ Joren: Да, это решило бы эту проблему. Я думаю, что большинство людей теперь понимают, что с самого начала было бы лучше иметь структурную типизацию на делегатах, но этот корабль отплыл. Это было бы довольно большое изменение, чтобы изменить его сейчас. Тем не менее, наблюдается повышенный интерес к структурной типизации, поэтому я не хотел бы заявлять, что нет шансов на это. –

0

Если вы ...

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

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

(Правда, это скорее обходным, чем раствор)

+1

Да, я знаю :) Это не отвечает на мой вопрос, но спасибо :) –

Смежные вопросы