I am attempting to add compile time checks to code which previously took the string name of a data object's property and a value of type 'object'. I am doing this in order to ensure the property and value are actually of the same type to prevent cases where they are not from introducing a runtime bug.
I am handling the compile time check by creating a method which takes an expression of type Expression<Func<TDataObject, TPropertyValue>> and a parameter of type TPropertyValue. From this, I can inspect the expression to get the name of the property that would be returned and then use the same logic we have today with strings and value as object type.
public interface IPropertyDictionary<TDataObject> where TDataObject : class
{
void AddIfSameType<TProperty>(
Expression<Func<TDataObject, TProperty>> propertyAccessExpression,
TProperty propertyValue);
}
The following works as expected:
// Allowed
propDictionary.AddIfSameType(e => e.IntProperty, 123);
// Flagged by intellisense (though the expression is flagged rather than second parameter...)
propDictionary.AddIfSameType(e => e.IntProperty, "asdf");
However, this does not work as expected:
// Not flagged as error
propDictionary.AddIfSameType(e => e.IntProperty, 123L);
With that, C# infers TPropertyValue to be a long rather than an int. In the debugger, I can see that the expression is being transformed to cast it to a long:
e => Convert(e.IntProperty)
In my ideal case, C# would prefer the type of IntProperty when making it's type inference and raise a compile time error indicating casting from long to int requires an explicit cast. Is there are way to indicate to C# that it should only use the first parameter of the method when inferring the type? The only alternative I have at the moment is to explicitly provide the type parameter:
// Flagged by intellisense
propDictionary.AddIfSameType<int>(e => e.IntProperty, 123L);
But in the 99% case people will not pass a type parameter and I would not expect them to realize they need to do so in this situation. As a result, their bug again becomes one of the runtime errors that I am eager to avoid.