我有一个有趣的问题。
public Func<T, int> GetLambdaFor<T>()
{
// ....
}
public void SetLambdaForAnyType(Func<?, int> lambda)
{
// ....
}
在上面的代码示例中,我想知道在检索特定类型的{时,是否可以使用SET方法在Generic
中指定可替换的lambda expression
C#
。 {1}} Generic
使用GET方法。
那么,让我举一个例子(当然它的特点是破碎lambda expression
,我想知道是否有可能,如果可行,怎么做):
C#
我希望现在更有意义。有任何想法吗?如果不可能,还有其他可能性吗?
答案 0 :(得分:4)
lambda表达式不能引入泛型参数,没有语法。您将不得不使用泛型方法而不是lambdas,并使用反射为特定类型构造封闭的泛型方法,如下所示(代码未测试):
public Func<T, int> GetLambdaFor<T> ()
{
return GetLambdaFor<T> (m_method, m_target) ;
}
public void SetLambdaForAnyType (Func<object, int> lambda)
{
if (lambda == null) throw new ArgumentNullException ("lambda") ;
// delegate complicated signature checks to CLR
try
{
var definition = lambda.Method.GetGenericMethodDefinition () ;
GetLambdaFor<Dummy> (definition, lambda.Target) ;
m_method = definition ;
m_target = lambda.Target ;
}
catch (Exception e)
{
throw new ArgumentException ("lambda", e) ;
}
}
private sealed class Dummy {}
private MethodInfo m_method ;
private object m_target ;
static Func<T, int> GetLambdaFor<T> (MethodInfo method, object target)
{
return (Func<T, int>) Delegate.CreateDelegate (typeof (Func<T, int>),
target, method.MakeGenericMethod (typeof (T))) ;
}
然后你就像这样使用它
// in your class
private static int GetValueFromGenerator<T> (T a)
{
return new SomeValueGenerator<T> (a).GetValue () ;
}
MyClass.SetLambdaForAnyType (GetValueFromGenerator) ;
最后,如果你的'lambdas'将始终是这种形式,你可能想要为GetValue
引入一个接口而不是动态创建通用方法,为这些生成器创建泛型类型,激活他们并投向IGetValue
。
答案 1 :(得分:3)
你可以做到,当然。你在这种类型中失去了类型安全性,但我们知道从外部角度看它也能正常工作:
public class Foo
{
private Dictionary<Type, Delegate> dictionary =
new Dictionary<Type, Delegate>();
public Func<T, int> GetLambdaFor<T>()
{
return dictionary[typeof(T)] as Func<T, int>;
}
public void SetLambdaFor<T>(Func<T, int> func)
{
dictionary[typeof(T)] = func;
}
}
当然,如果您想处理该类型没有条目的情况,您可能希望使用字典中的TryGetValue
。
另一种选择是使用线程静态字段:
public class Foo2<T>
{
[ThreadStatic]
public Func<T, int> Generator { get; set; }
}
然后它就像:
一样简单Foo2<string>.Generator = s => 5;
int result = Foo2<string>.Generator("asdf");