【问题标题】:How to convert a generic C# Action<T1> to Action<T2>如何将通用 C# Action<T1> 转换为 Action<T2>
【发布时间】:2015-07-06 19:53:27
【问题描述】:

我一直在用 C# 做一些工作来学习和创造一些东西;不幸的是,我对 C# 很陌生,我在转换方面遇到了一些问题。

我有一个 Type1 的 Action,我想将它转换为 Type2;这两种类型在编译时都是已知的。这是我要归档的示例代码。

public class Example <Resolve, Reject>
{
    protected Resolve resolved;
    protected Reject rejected;

    public Example( Resolve value ) { resolved = value; }
    public Example( Reject value ) { rejected = value;  }

    public void invoke( Action<Resolve> callback ) {
        if( null != resolved ) { callback (resolved ); }
        else if( null != rejected ) {
            // How to cast action from Action <Resolve> to Action <Rejected>
            // and invoke it with the rejected value??
            callback ( rejected );
        }
        else throw new ApplicationException( "Not constructed" );
    }
}

public static void Main (string[] args)
{
    Console.WriteLine ("Start");

    var example1 = new Example <string, System.ArgumentException> ( "Str argument" );

    example1.invoke (msg => {
        // Here the msg is a string ok!
        if (msg is string) { Console.WriteLine (msg); }
        else { Console.WriteLine ("Exception"); }
    });

    var example2 = new Example <string, System.ArgumentException> ( new ArgumentException("An exception") );

    example2.invoke (msg => {
        // Here msg should be an ArgumentException.
        if (msg is string) { Console.WriteLine (msg); }
        else { Console.WriteLine ("Exception"); }
    });


    Console.WriteLine ("Done");
    Console.ReadLine ();
}

我无法控制类型,所以我不能将一个类型转换为另一个类型,即使我可以实现的规范也要求我必须使用 Resolve 或 Reject 值来解决回调,具体取决于某些运行时发生的情况。

你能帮帮我吗?

【问题讨论】:

  • 看来你真的需要传入两个单独的动作。
  • 你在这里描述的是一个有区别的联合。正如@juharr 所说,您需要根据值是T1 还是T2 类型来调用两个单独的操作。看看github.com/DavidArno/SuccincT/wiki/UnionT1T2,它是一个联合类型,支持通过模式匹配调用动作,在 Succinc 库中。你可能会发现它提供了你需要的东西。 (免责声明:我写的)

标签: c# generics casting delegates


【解决方案1】:

免责声明:我是以下开源库的作者

如果您使用 Succinc<T> 提供的可区分联合类型和模式匹配,您可以在此处简单地写下您需要的内容:

public static void MessageOrException(Union<string, ArgumentException> value)
{
    value.Match().Case1().Do(Console.WriteLine)
                 .Else(Console.WriteLine("Exception")
                 .Exec();
}


public static void Main (string[] args)
{
    Console.WriteLine ("Start");

    var example1 = new Union<string, ArgumentException> ("Str argument");
    MessageOrException(example1);  // Writes "Str argument"

    var example2 = 
        new Union<string, ArgumentException>(new ArgumentException("An exception"));
    MessageOrException(example2); // Writes "Exception"

    Console.WriteLine ("Done");
    Console.ReadLine ();
}

【讨论】:

  • 嘿!我在看你的图书馆,它看起来真的很好!做得好!我将不得不尝试一下,看看是否可以通过一些调整来完成我想要的。你看主要的问题是我只能有一个回调,所以给我一些时间来尝试你的解决方案并进行一些更改,也给其他可能有不同解决方案的人一些时间!
猜你喜欢
  • 2012-09-09
  • 2015-11-06
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
相关资源
最近更新 更多