Мне нужен метод, подобный следующему:
// takes in a DefaultValue type as an Expression Function, with an argument
public void Register<T, TDefaultValueArgs>(Expression<Func<TDefaultValueArgs, T>> defaultValue)
{
// stuff happens here.....
}
Я хотел бы добавить две перегруженные версии метода.Один, где defautlValue - это простой экземпляр T, а другой - где defaultValue - это функция выражения без параметра.
Я пришел к этому (непроверенному) решению:
// takes in a DefaultValue type
public void Register<T>(T defaultValue)
{
// The statement below would be better, but isn't valid: "A lambda expression with a statement body cannot be converted to an expression tree"
// Expression<Func<object, T>> defaultValueFunc = (o) => { return defaultValue; };
Expression<Func<DefaultValueContainer<T>, T>> defaultValueFunc = (m => m.GetDefaultValue(defaultValue));
Register<T, DefaultValueContainer<T>>(defaultValueFunc);
}
// takes in a DefaultValue type as an Expression Function
public void Register<T>(Expression<Func<T>> defaultValue)
{
// The statement below would be better, but isn't valid: "A lambda expression with a statement body cannot be converted to an expression tree"
// Expression<Func<object, T>> defaultValueFunc = (o) => { return defaultValue.Compile().Invoke(); };
Expression<Func<DefaultValueContainer<T>, T>> defaultValueFunc = (m => m.GetDefaultValue(defaultValue));
Register<T, DefaultValueContainer<T>>(defaultValueFunc);
}
private class DefaultValueContainer<T>
{
public DefaultValueContainer()
{ }
public T GetDefaultValue(T defaultValue)
{
return defaultValue;
}
public T GetDefaultValue(Expression<Func<T>> defaultValue)
{
return defaultValue.Compile().Invoke();
}
}
IЗатем я предполагаю, что в моем исходном методе Regsiter<T, TDefaultValueArgs>
я мог бы сделать что-то вроде этого:
T resolvedDefaultValue = default(T);
if (typeof(TDefaultValueArgs).Equals(typeof(DefaultValueContainer<T>)))
{
var defaultValueContainer = Activator.CreateInstance<TDefaultValueArgs>();
resolvedDefaultValue = defaultValue.Compile().Invoke(defaultValueContainer);
}
Все это, включая использование DefaultValueContainer<T>
, кажется глупым.Должен быть лучший способ?
Примечание. По причинам, выходящим за рамки этого примера, я должен использовать тип выражения, а не только делегат.