Say I have a function, for example:
public TProperty Foo<TClass, TProperty>(TClass instance, Expression<Func<TClass, TProperty>> expression) { ... }
But then I understand that it should only be used for value types, so I add a restriction
public TProperty Foo<TClass, TProperty>(TClass instance, Expression<Func<TClass, TProperty>> expression) where TProperty : struct { ... }
But then I discovered that this would not allow me to pass expressions that take the nullable TProperty value. The only way I can handle this is to do the following:
public TProperty Foo<TClass, TProperty>(TClass instance, Expression<Func<TClass, TProperty?>> expression) where TProperty : struct { ... }
But now I have to support two methods that do the same thing, except that it is nullables and the other is not.
Further, I can not extract them into the general method, because, despite the fact that there is a transformation from T to T?, Apparently there is no conversion from
Expression<Func<T1, T2>>
to
Expression<Func<T1, T2?>>
If the body of these methods is complex, I really do not want to support two separate versions, especially if in fact it is a number of functions.
Is there a way to avoid code duplication and still have a compiler so that the expression should end with either a value type or zero?
(I am currently using C # 3.5, but I am open to later versions if they provide a clean solution.)