我有一个可以注册func来解析每种类型的id值的单例:
public void RegisterType<T>(Func<T, uint> func)
例如:
RegisterType<Post>(p => p.PostId );
RegisterType<Comment>(p => p.CommentId );
然后我想解析一个对象的id,如下所示:
GetObjectId(myPost);
其中GetObjectId定义为
public uint GetObjectId(object obj)
问题是,我如何为每个func存储一个引用以便最近调用它。 问题是每个func都有不同的T类型,我不能这样做:
private Dictionary<Type, Func<object, uint>> _typeMap;
如何解决?表达树?
问候 埃塞基耶尔
答案 0 :(得分:2)
您有两种选择:
将GetObjectId
更改为采用T
的通用函数
然后,您可以store the Func<T, uint>
s in a generic static class通过撰写FuncStorage<T>.Value(obj)
来调用它们。
使用表达式树创建调用Func<object, uint>
的{{1}}(使用强制转换)并将其放入Func<T, uint>
。
编辑:您不需要表达式树来执行此操作;你可以使用一个普通的lambda表达式,它转换为Dictionary<Type, Func<object, uint>>
。我正在考虑相反的情况(从非泛型代理生成泛型委托),这需要表达式树。
答案 1 :(得分:2)
你不需要像你建议的那样做表达树,只需要在注册时嵌套函数。
public void RegisterType<T>(Func<T, uint> func){
_typeMap.Add(typeof(T), obj=>func((T)obj));
}
答案 2 :(得分:1)
public class Registration
{
public static Registration Instance = new Registration();
private Registration()
{
}
private Dictionary<Type, object> Dictionary = new Dictionary<Type, object>();
public void Register<T>(Func<T, uint> aFunc)
{
Dictionary[typeof(T)] = aFunc;
}
public uint GetId<T>(T aT)
{
var f = Dictionary[typeof(T)];
var g = (Delegate)f;
return (uint) g.DynamicInvoke(aT);
}
}
答案 3 :(得分:1)
问题是每个func都有一个 不同的T型,我不能这样做 像这样的东西:
private Dictionary<Type, Func<object, uint>> _typeMap;
我不确定你为什么这么说。这有效:
class Post
{
public uint PostId { get; set; }
}
static public void RegisterType<T>(Func<T, uint> getUintFromT)
{
Func<object, T> toT = (t => (T)t);
Func<object, uint> getUintFromObject =
@object => getUintFromT(toT(@object));
_typeMap.Add(typeof(T), getUintFromObject);
}
static public uint GetObjectId(object obj)
{
return _typeMap[obj.GetType()](obj);
}
用法:
class Program
{
private static Dictionary<Type, Func<object, uint>> _typeMap
= new Dictionary<Type, Func<object, uint>>();
static void Main(string[] args)
{
RegisterType<Post>(p => p.PostId);
Post myPost = new Post();
myPost.PostId = 4;
var i = GetObjectId(myPost);
Console.WriteLine(i);
Console.ReadKey();
}
}
答案 4 :(得分:1)
@SLacks,按照你的建议我改变了我的方法:
private Dictionary<Type, Func<object, uint>> _typeMap;
public void RegisterType<T>(uint typeId, Func<T, uint> func)
{
_typeMap[typeof(T)] = (o) => func((T)o);
}
public uint GetObjectId(object obj)
{
return _typeMap[obj.GetType()](obj);
}
谢谢!
答案 5 :(得分:0)
我无法将GetObjectId
更改为GetObjectId<T>
,因为我不知道运行时的类型。
所以,我已将字典定义更改为:
private Dictionary<Type, Delegate> _typeMap
然后通过Reflection:
调用它public uint GetObjectId(object obj)
{
uint id = 0;
var objType = obj.GetType();
// busco si el type está registrado
if (_typeMap.Keys.Contains(objType))
{
id = (uint) _typeMap[objType].Method.Invoke(obj, new object[] { obj } );
}
return id;
}
非常感谢你