繁体   English   中英

转换动作<T>行动<object>

[英]Convert Action<T> to Action<object>

我被困住了。

如何在 C# 中将Action<T> to an Action<Object>

问候马格努斯

这是您要求的示例(可以在最后一行添加类型检查以正确处理无效的强制转换异常以更加用户友好):

public Action<object> Convert<T>(Action<T> myActionT)
{
    if (myActionT == null) return null;
    else return new Action<object>(o => myActionT((T)o));
}

不过,也许您可​​以提供有关该任务的更多详细信息,因为现在它看起来有点奇怪。

我假设你有这样的事情:

void Foo(Action<object> action) { }

Action<something> myaction;

并希望转换 myaction 以便您可以将其传递给 Foo。

那行不通。

Foo 可以将任何对象传递给其类型从对象派生的操作。 但是 myaction 只接受从某物派生的对象。

我今天正在寻找一种方法来做到这一点,并偶然发现了这篇文章。 真的,我发现的唯一简单方法是将 Action<string> 包装在一个新的 Action<object> 中。 就我而言,我将我的操作推送到并发字典中,然后按类型检索它们。 实际上,我正在处理一个消息队列,其中可以定义操作来处理具有特定类型输入的消息。

var _actions = new ConcurrentDictionary<Type, Action<object>>();
Action<string> actionStr = s => Console.WriteLine(s);
var actionObj = new Action<object>(obj => { var castObj = (V)Convert.ChangeType(obj, typeof(V)); actionStr(castObj); } );
_actions.TryAdd(typeof(string), actionObj);

您可以像这样添加通用参数

    Action<object> Function<T>(Action<T> act) where T : class
    {
        return (Action<object>)act;
    }

不确定转换是什么意思... Action 是动作委托的通用声明...如果您想要一个适用于“对象”的动作委托,您可以执行以下操作:

var myAction = new Action<object>(obj=> ... );

追踪行动<t> lambdas 作为动作<object><div id="text_translate"><p>过去问过类似的问题:</p><ul><li> <a href="https://stackoverflow.com/questions/3444246/convert-actiont-to-actionobject" rel="nofollow noreferrer">将 Action&lt;T&gt; 转换为 Action&lt;object&gt;</a></li><li> <a href="https://stackoverflow.com/questions/7609629/expose-actiont-as-actionobject" rel="nofollow noreferrer">将 Action&lt;T&gt; 公开为 Action&lt;object&gt;</a></li><li> <a href="https://stackoverflow.com/questions/20800075/how-to-cast-object-to-actiont" rel="nofollow noreferrer">如何将 object 转换为 Action&lt;T&gt;</a></li></ul><p> 所有人都得到了将Action&lt;T&gt; myActionT包装成匿名的解决方案new Action&lt;object&gt;(o =&gt; myActionT((T)o));<br> 我的用例是,最初输入的 lambda 是一个数据订阅回调,将其包装成一个匿名回调意味着我失去了使用原始Action&lt;T&gt;取消订阅的能力</p><p>我将其缩小到这个样板示例:</p><pre> internal class Demo { public class Dispatcher { private List&lt;Action&lt;object&gt;&gt; callbacks = new List&lt;Action&lt;object&gt;&gt;(); public void Subscribe&lt;T&gt;(Action&lt;T&gt; cbk) { callbacks.Add(cbk); // &lt;- compile error, Action&lt;T&gt; is contravariant } public void Unsubscribe&lt;T&gt;(Action&lt;T&gt; cbck) { callbacks.Remove(cbck); // &lt;- compile error } } private static void Handler(int v) {} private static void Handler(string v) {} public static void Main() { var dispatcher = new Dispatcher(); dispatcher.Subscribe&lt;int&gt;(Handler); dispatcher.Subscribe&lt;string&gt;(Handler); dispatcher.Unsubscribe&lt;int&gt;(Handler); } }</pre><p> 当然我可以 go 重载Subscribe (因为我实际上只需要值类型)<br> 是否有更好/更优雅的方法来正确跟踪通用Action回调?</p><p> <strong>稍后编辑</strong>:添加有关我的用例的更多详细信息:</p><ul><li> 我包装了键值(字符串)更新的数据馈送</li><li>客户端可以订阅字段,并且可以选择接收从字符串转换为其他类型的值(我使用TypeDescriptor.GetConverter(type).ConvertFromString(fieldValue)来处理转换)</li></ul><p> 例如:</p><pre> Subscribe&lt;decimal&gt;("price", (decimal px) =&gt; { /* do smthg with price*/ }) Subscribe&lt;bool&gt;("opened", (bool opened) =&gt; {... }) Subscribe&lt;string&gt;("code", (string code) =&gt; {... })</pre><p> 我觉得我目前的方法(函数指针/委托,跟踪订阅类型)陷入了困境,但我没有找到更直接的方法来实现这一点(除了用我需要的类型重载Subscribe之外,这可能是明智的 KISS 选择)</p></div></object></t>

[英]Track Action<T> lambdas as Action<object>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何转换表达式 <Action<T, object> &gt;表达 <Action<T, U> &gt;? 揭露行动 <T> 作为行动 <object> 追踪行动<t> lambdas 作为动作<object><div id="text_translate"><p>过去问过类似的问题:</p><ul><li> <a href="https://stackoverflow.com/questions/3444246/convert-actiont-to-actionobject" rel="nofollow noreferrer">将 Action&lt;T&gt; 转换为 Action&lt;object&gt;</a></li><li> <a href="https://stackoverflow.com/questions/7609629/expose-actiont-as-actionobject" rel="nofollow noreferrer">将 Action&lt;T&gt; 公开为 Action&lt;object&gt;</a></li><li> <a href="https://stackoverflow.com/questions/20800075/how-to-cast-object-to-actiont" rel="nofollow noreferrer">如何将 object 转换为 Action&lt;T&gt;</a></li></ul><p> 所有人都得到了将Action&lt;T&gt; myActionT包装成匿名的解决方案new Action&lt;object&gt;(o =&gt; myActionT((T)o));<br> 我的用例是,最初输入的 lambda 是一个数据订阅回调,将其包装成一个匿名回调意味着我失去了使用原始Action&lt;T&gt;取消订阅的能力</p><p>我将其缩小到这个样板示例:</p><pre> internal class Demo { public class Dispatcher { private List&lt;Action&lt;object&gt;&gt; callbacks = new List&lt;Action&lt;object&gt;&gt;(); public void Subscribe&lt;T&gt;(Action&lt;T&gt; cbk) { callbacks.Add(cbk); // &lt;- compile error, Action&lt;T&gt; is contravariant } public void Unsubscribe&lt;T&gt;(Action&lt;T&gt; cbck) { callbacks.Remove(cbck); // &lt;- compile error } } private static void Handler(int v) {} private static void Handler(string v) {} public static void Main() { var dispatcher = new Dispatcher(); dispatcher.Subscribe&lt;int&gt;(Handler); dispatcher.Subscribe&lt;string&gt;(Handler); dispatcher.Unsubscribe&lt;int&gt;(Handler); } }</pre><p> 当然我可以 go 重载Subscribe (因为我实际上只需要值类型)<br> 是否有更好/更优雅的方法来正确跟踪通用Action回调?</p><p> <strong>稍后编辑</strong>:添加有关我的用例的更多详细信息:</p><ul><li> 我包装了键值(字符串)更新的数据馈送</li><li>客户端可以订阅字段,并且可以选择接收从字符串转换为其他类型的值(我使用TypeDescriptor.GetConverter(type).ConvertFromString(fieldValue)来处理转换)</li></ul><p> 例如:</p><pre> Subscribe&lt;decimal&gt;("price", (decimal px) =&gt; { /* do smthg with price*/ }) Subscribe&lt;bool&gt;("opened", (bool opened) =&gt; {... }) Subscribe&lt;string&gt;("code", (string code) =&gt; {... })</pre><p> 我觉得我目前的方法(函数指针/委托,跟踪订阅类型)陷入了困境,但我没有找到更直接的方法来实现这一点(除了用我需要的类型重载Subscribe之外,这可能是明智的 KISS 选择)</p></div></object></t> 转换动作 <T> 回调等待 将委托转换为行动 <T> (行动 <T1,T2> ) 使用 Action(T, object) 时出错 如何将对象转换为Action <T> Action <T>或Action <in T>? 转换表达式 <Action<T> &gt;表达 <Func<T> &gt; 将自定义委托类型转换为动作<Object>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM