对不同类型 Func 的引用

发布于 2024-10-19 14:05:35 字数 612 浏览 2 评论 0 原文

我有一个单例,可以注册一个函数来解析每种类型的 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 都有不同的 T 类型,我不能做这样的事情:

private Dictionary<Type, Func<object, uint>> _typeMap;

如何解决它?表达树?

问候 埃泽奎尔

I have a singleton that can register a func to resolve an id value for each type:

public void RegisterType<T>(Func<T, uint> func)

for example:

RegisterType<Post>(p => p.PostId );
RegisterType<Comment>(p => p.CommentId );

and then i want to resolve the id for an object, like these:

GetObjectId(myPost);

where GetObjectId definition is

public uint GetObjectId(object obj)

The question is, how can i store a reference for each func to invoke it lately.
The problem is that each func has a different T type, and I can't do something like this:

private Dictionary<Type, Func<object, uint>> _typeMap;

How can resolve it? Expression trees?

regards
Ezequiel

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

败给现实 2024-10-26 14:05:35

您不需要表达式树按照您建议的方式执行此操作,只需在注册函数时嵌套该函数即可。

public void RegisterType<T>(Func<T, uint> func){
             _typeMap.Add(typeof(T), obj=>func((T)obj));
}

You don't need Expression Trees to do it the way you are suggesting, just need to nest the function when registering it.

public void RegisterType<T>(Func<T, uint> func){
             _typeMap.Add(typeof(T), obj=>func((T)obj));
}
夜清冷一曲。 2024-10-26 14:05:35

您有两个选择:

  1. GetObjectId 更改为采用 T 的通用函数。
    然后,您可以 Func 存储在泛型中静态类,并通过编写 FuncStorage.Value(obj) 来调用它们。

  2. 使用表达式树创建调用 FuncFunc(使用强制转换)并将它们放入您的Dictionary>中。
    编辑:你不需要表达式树来做到这一点;您可以使用普通的 lambda 表达式来转换为 T。我正在考虑相反的情况(从非泛型委托生成泛型委托),这确实需要表达式树。

You have two options:

  1. Change GetObjectId to a generic function that takes a T.
    You can then store the Func<T, uint>s in a generic static class and call them by writing FuncStorage<T>.Value(obj).

  2. Use expression trees to Create Func<object, uint>s that calls the Func<T, uint> (using a cast) and put those in your Dictionary<Type, Func<object, uint>>.
    EDIT: You don't need expression trees to do that; you can use a normal lambda expression which casts to T. I was thinking of the reverse case (generating a generic delegate from a non-generic one), which does require expression trees.

情话已封尘 2024-10-26 14:05:35
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);
        }
    }
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);
        }
    }
潜移默化 2024-10-26 14:05:35

问题是每个函数都有一个
不同的T型,我做不到
像这样的东西:

私有字典<类型,Func<对象,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();

    }
}

The problem is that each func has a
diferent T type, and i cant do
something like these:

private Dictionary<Type, Func<object, uint>> _typeMap;

I'm not sure why you say this. This works:

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);
}

Usage:

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();

    }
}
橘虞初梦 2024-10-26 14:05:35

@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);
}

谢谢!

@SLacks, following your advise i have changed my approach to:

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);
}

thanks!

素罗衫 2024-10-26 14:05:35

我无法将 GetObjectId 更改为 GetObjectId 因为我不知道运行时的类型。

所以,我将字典定义更改为:

private Dictionary<Type, Delegate> _typeMap 

然后通过反射调用它:

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;
}

非常感谢大家

I cant change GetObjectId to GetObjectId<T> because i don´t known the type on runtime.

So, i have changed the dictionary definition to:

private Dictionary<Type, Delegate> _typeMap 

and then invoke it via 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;
}

Thank you all so much

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文