Как заставить компилятор C # выводить универсальные типы? - PullRequest
6 голосов
/ 30 июля 2009

У меня есть следующий метод:

public TResult Get<TGenericType, TResult>()
                          where TGenericType : SomeGenericType<TResult>
                          where TResult : IConvertible {
   //...code that uses TGenericType...
   //...code that sets someValue...
   return (TResult) someValue;
}

Прямо сейчас, пользователь этого метода должен использовать его так:

//Notice the duplicate int type specification
int number = Get<SomeGenericType<int>, int>();

Почему я должен указывать TResult в определении метода? Компилятор уже знает TResult, так как я указал его в TGenericType. В идеале (если бы компилятор C # был немного умнее), мой метод должен выглядеть следующим образом:

public TResult Get<TGenericType>()
                          where TGenericType : SomeGenericType<TResult>
                          where TResult : IConvertible {
   //...code that uses TGenericType...
   //...code that sets someValue...
   return (TResult) someValue;
}

Таким образом, пользователь может просто использовать это так:

//Much cleaner
int number = Get<SomeGenericType<int>>();

Есть ли способ сделать то, что я хочу сделать?

Ответы [ 2 ]

8 голосов
/ 30 июля 2009

Спецификация C # не позволяет выводить половину аргументов типа. Вы должны либо позволить компилятору вывести все аргументы типа (что не всегда применимо, как в вашем случае), либо вручную указать все из них.

ОБНОВЛЕНИЕ (ответ на комментарий): Хотя я не в команде C #, чтобы дать полный ответ на ваш вопрос, я предполагаю, что сложность разрешения перегрузки (которая уже поражает воображение) ; вы знаете, что если вы прочитаете этот раздел спецификации C #), то значительно увеличится, если они захотят разрешить вывод половины типов, а половину нет (особенно если учесть тот факт, что вы можете перегружать методы только числом общих аргументов).

1 голос
/ 30 июля 2009

Это зависит ...

Если вы просто используете SomeGenericType<TResult>, вы можете сделать:

public TResult Get<TResult>() where TResult : IConvertible {
    SomeGenericType<TResult> myInstance = ...
    //...code that sets someValue...
    return (TResult) someValue;
}

В этом случае не обязательно использовать первый тип. Поскольку ваш пример не передает явно SomeGenericType<TResult> в качестве параметра, он предполагает, что это возможно.

В противном случае вам необходимо полностью указать все ваши общие аргументы. К сожалению, это так же, как в C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...