#c# #generics #types #inference
#c# #общие сведения #типы #вывод
Вопрос:
Я не уверен, как сформулировать этот вопрос кратко, не приводя просто пример, поэтому здесь:
public interface IThing<T>
{
void Do(T obj);
}
public class ThingOne : IThing<int>
{
public void Do(int obj)
{
}
}
public class ThingTwo : IThing<string>
{
public void Do(string obj)
{
}
}
public class ThingFactory
{
public IThing<T> Create<T>(string param)
{
if (param.Equals("one"))
return (IThing<T>)new ThingOne();
if (param.Equals("two"))
return (IThing<T>)new ThingTwo();
}
}
class Program
{
static void Main(string[] args)
{
var f = new ThingFactory();
// any way we can get the compiler to infer IThing<int> ?
var thing = f.Create("one");
}
}
Комментарии:
1. Это не вывод типа — ваш возвращаемый тип не является статическим, т. Е. Заранее неизвестно, будет ли возвращен TypeOne или TypeTwo.
2. Добавляя к ответам, ваш код не должен быть даже компилируемым без этого типа «вывод» из-за
Create<T>
метода и особенно из-за ваших приведений.new ThingTwo()
не может быть приведено кIThing<T>
, то же самое верно дляThingOne
. Похоже, вам нужен динамически типизированный язык. Или вы допустили (собираетесь допустить) ошибку в своем проекте.
Ответ №1:
Вопрос, похоже, здесь:
// any way we can get the compiler to infer IThing<int> ?
var thing = f.Create("one");
Нет. Вам нужно будет явно указать тип:
var thing = f.Create<int>("one");
Вы не можете вывести тип возвращаемого значения, не имея параметра, используемого специально в методе. Компилятор использует параметры, переданные методу, для вывода типа T
, и в данном случае это параметр с одной строкой, без параметров типа T
. Таким образом, нет способа вывести это для вас.
Ответ №2:
Нет, вы не можете этого сделать, потому что результат вашего Create
фабричного метода будет оцениваться во время выполнения на основе значения параметра. Универсальные интерфейсы предназначены для обеспечения безопасности во время компиляции, и в вашем случае у вас не может быть такой безопасности, потому что значение параметра будет известно только во время выполнения.