У меня есть пример данных:
public struct Task
{
public int INT;
public string STRING;
public DateTime? NULLABLEDATETIME;
}
И функция, которая его использует:
public KeyValuePair<Expression<Func<Task, object>>, object> Marry(Expression<Func<Task, object>> key, object value)
{
return new KeyValuePair<Expression<Func<Task, object>>, object>(key, value);
}
Вот пример вызова функции:
Marry(t => t.INT, 1984);
Marry(t => t.NULLABLEDATETIME, DateTime.Now);
Marry(t => t.STRING, "SomeSting");
Этот код работает, без вопросов. К сожалению, мы также можем вызывать функции, как показано ниже, потому что String и int оба унаследованы от класса объекта:
Marry(t => t.INT, "SomeSting");
Я хочу сказать компилятору, что первый и второй параметры имеют одинаковый тип данных: int -> int
, string -> string
, DateTime? -> DateTime?
и проверяют его во время компиляции. Я попробовал это:
public KeyValuePair<Expression<Func<Task, T1>>, T2> Marry<T1, T2>(Expression<Func<Task, T1>> key, T2 value)
where T2 : T1
{
return new KeyValuePair<Expression<Func<Task, T1>>, T2>(key, value);
}
Это почти работает, и если я попытаюсь ввести неправильные данные, подобные этому Marry(t => t.INT, "SomeSting");
, компилятор выдаст ошибку:
Тип 'string' нельзя использовать в качестве параметра типа 'T2' в универсальном типе или методе 'Task.Marry (System.Linq.Expressions.Expression>, T2)'. Не существует неявного преобразования ссылок из 'string' в 'int'.
Но это решение не работает с null
. Когда я звоню Marry(t => t.NULLABLEDATETIME, null);
, компилятор говорит:
Аргументы типа для метода 'Marry (System.Linq.Expressions.Expression>, T2)' не могут быть выведены из использования. Попробуйте указать аргументы типа явно.
Почему? Я уже знаю тип данных: DateTime?
. Я не хочу явно звонить Marry<DateTime?>(t => t.NULLABLEDATETIME, null);
. Как я могу это сделать - или есть другой способ проверить некоторые типы параметров функции во время компиляции?