2015-02-26 6 views
0

Предположим, что в моем классе Utils есть статический метод, который задает значение свойства.Как изменить, с каким аргументом является тип, выводимый в общих методах?

public static SetPropertyValue<TDest, TVal> 
    (Expression<Func<TDest, TVal>> expression, 
    TDest destination, 
    TVal value) 
{ 
    // ... 
} 

Кроме того, существует класс:

public class DataObject { public short Code { get; set; } } 

И код использования:

DataObject obj = new DataObject(); 
int code = 404; 
Utils.SetPropertyValue(m => m.Code, obj, code); 

Когда выше код выполняется, то выражение изменяется на m => Convert(m.Code), поскольку третий параметр задано значение integer, и выражение ожидает short. Это означает, что система вывода типов решила предпочесть третий аргумент для определения типа TVal.

Я желаю этого метода в третий аргумент (значение) должно быть ограничено типа, определенного первого аргумента (выражение). Это возможно? Если да, то как?

ответ

2

Нет, вы не можете повлиять на выводе типа, что путь - и если он сделал Infer TVal, как short, ваш код не будет компилироваться, потому что нет неявного преобразования из int в short.

Конечно, лучшим решением будет просто избегать использования двух различных типов, чтобы начать с:

short code = 404; 
Utils.SetPropertyValue(m => m.Code, obj, code); 

Теперь типы будут выведены правильно, и не будет каких-либо преобразований.

+0

Спасибо, Джон! Но проблема с этим связана с тем, что компилятор позволит вам вставить «недействительный» тип, но без малейшего преобразования моей лямбда. Почему это так? –

+0

@ KornelijePetak: Почему бы и нет? Тип 'm.Code' является' short', и это неявно конвертируется в 'int'. Например, вы можете написать метод: 'public int GetCode (DataObject m) {return m.Code; } '- и это в основном то, о чем компилятор думает, когда видит лямбда-выражение. Опять же - подумайте о том, почему вы * не ожидаете, что компилируете ... –

+2

@KornelijePetak - это потому, что вы используете конкретное * злоупотребление * системы выражений, чтобы попытаться идентифицировать свойство объекта. Система никогда не была * разработана *, чтобы вы могли использовать выражение для идентификации свойств. Компилятор C# не имеет никакого способа сделать вывод о том, что, несмотря на то, что вы передаете выражение, которое обращается к getter свойства, код в 'SetPropertyValue' фактически планирует получить доступ к установщику. –