jdp*_*nix 3 c# generics boxing
假设我有一些类Func
根据传递给它的泛型类型调用一个,我有一个类所需的公共接口:
var r = new Resolver();
var i = r.Invoke(10); // invokes some function `Func<int,int>`
var j = r.Invoke("Hello"); // Same, but `Func<string,string>`
var k = r.Invoke(10, 10); // Same but 'Func<int,int,int>`
Run Code Online (Sandbox Code Playgroud)
我有这样的实现:
class Resolver {
readonly IDictionary<Type, Func<object, object>> _funcs = new Dictionary<Type, Func<object, object>>();
public Resolver() {
_funcs.Add(typeof(int), o => (int)o*(int)o);
_funcs.Add(typeof(string), o => (string)o + (string)o);
// and so on;
}
public T Invoke<T>(T t1) {
return (T) _funcs[typeof (T)](t1);
}
public T Invoke<T>(T t1, T t2) {
return (T)_funcs[typeof(T)](t1);
}
}
Run Code Online (Sandbox Code Playgroud)
但是对于值类型来说性能是可怕的,因为由于Func<,>
具有object
泛型类型的内部实现而引起的装箱.
有没有办法实现我想要的公共接口,避免拳击值类型?我也不介意实现中的静态类型安全,但可以没有.
你可以做以下简单的技巧(不比你当前的实现更安全或更不安全):
class Resolver
{
readonly IDictionary<Type, object> _unaryFuncs = new Dictionary<Type, object>();
readonly IDictionary<Type, object> _binaryFuncs = new Dictionary<Type, object>();
public Resolver()
{
_unaryFuncs.Add(typeof(int), new Func<int, int>(o => o * o));
_unaryFuncs.Add(typeof(string), new Func<string, string(o => o + o));
_binaryFuncs.Add(typeof(int), new Func<int, int, int>((x, y) => x + y));
// and so on;
}
public T Invoke<T>(T t1)
{
var f = _unaryFuncs[typeof(T)] as Func<T, T>;
return f(t1);
}
public T Invoke<T>(T t1, T t2)
{
var f = _binaryFuncs[typeof(T)] as Func<T, T, T>;
return f(t1, t2);
}
}
Run Code Online (Sandbox Code Playgroud)
您可能想要添加一些错误检查,如检查
T
函数是从字典中得到它之前注册.null
之后不是as
.并添加类型安全注册功能:
public void Register<T>(Func<T, T> unaryFunc)
{
_unaryFuncs[typeof(T)] = unaryFunc;
}
public void Register<T>(Func<T, T, T> binaryFunc)
{
_binaryFuncs[typeof(T)] = binaryFunc;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1272 次 |
最近记录: |