Hi, I have some example data:
public struct Task
{
public int INT;
public string STRING;
public DateTime? NULLABLEDATETIME;
}
And function, which uses it:
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);
}
Here is example of function call:
Marry(t => t.INT, 1984);
Marry(t => t.NULLABLEDATETIME, DateTime.Now);
Marry(t => t.STRING, "SomeSting");
This code works, no questions. Unfortunatly we can also call functions like below, because String and int are both inherited from object class:
Marry(t => t.INT, "SomeSting");
I want to say compiler, that first and second parameters have same data type: int -> int
, string -> string
, DateTime? -> DateTime?
and check it during compilation. I tried this:
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);
}
This almost works, and if I try to put wrong data like this Marry(t => t.INT, "SomeSting");
the compiler reports an error:
The type 'string' cannot be used as type parameter 'T2' in the generic type or method 'Task.Marry(System.Linq.Expressions.Expression>, T2)'. There is no implicit reference conversion from 'string' to 'int'.
But this solution does not work with null
. When I call Marry(t => t.NULLABLEDATETIME, null);
the compiler says:
The type arguments for method 'Marry(System.Linq.Expressions.Expression>, T2)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Why? I already know the data type: DateTime?
. I don't want to explicitly call Marry<DateTime?>(t => t.NULLABLEDATETIME, null);
. How can I do this - or is there another way to check some function parameter types during compilation?