Избегайте общих аргументов - PullRequest
3 голосов
/ 14 июня 2011

У меня есть следующий метод расширения, который утверждает, что свойство (Id) содержит указанный атрибут (TV):

public static void ShouldHave<T, TV, TT>(this T obj, Expression<Func<T, TT>> exp) {...}

Этот метод можно вызвать так:

MyDto myDto = new MyDto();
myDto.ShouldHave<MyDto, RequiredAttribute, int>(x => x.Id);

Компилируется просто отлично.Мне было интересно, если можно удалить T и TT из сигнатуры метода.T, потому что mustHave вызывается для T, поэтому нет необходимости указывать его явно.А TT - это тип свойства, на которое ссылается выражение (x.Id).

Ответы [ 3 ]

2 голосов
/ 14 июня 2011

Следующие компиляции:

public static void ShouldHave<T, TT>(this T obj, Expression<Func<T, TT>> exp)
{...}

MyDto myDto = new MyDto();
myDto.ShouldHave(x => x.Id);

В нем не указан аргумент типа TV, что является причиной того, что вам необходимо явно указать общие аргументы на сайте вызова.Если вам нужен этот аргумент, вам не повезло.

1 голос
/ 14 июня 2011

Автоматический вывод аргументов типа работает только в том случае, если в вызове метода указаны нет универсальных аргументов. Т.е. это:

myDto.ShouldHave<, RequiredAttribute, >(x => x.Id);

недопустимый синтаксис. Вы можете иметь «все или ничего».

Таким образом, если вы хотите сделать вывод T и TT, вам нужно передать информацию, содержащуюся в TV, как-то иначе. Например, одним из вариантов будет передача type атрибута в качестве параметра:

public static void ShouldHave<T, TT>(this T obj, 
                                     Expression<Func<T, TT>> exp, 
                                     Type attribute) {...}

(Очевидно, это потребует изменений в вашей реализации ShouldHave).

Тогда вы сможете вызывать метод следующим образом:

MyDto myDto = new MyDto();
myDto.ShouldHave(x => x.Id, typeof(RequiredAttribute));
0 голосов
/ 14 июня 2011

Попробуйте это:

public static void ShouldHave<TV>(this object obj, Expression<Func<object, object>> exp) {...}

Вы должны найти, что exp теперь состоит из реального выражения, окруженного приведением к объекту. Внутри вашего метода снимите гипс следующим образом:

Expression realExp = ((UnaryExpression) exp).Operand;

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

...