Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 为什么变量的泛型类型参数必须与设置它的相应OutArgument精确匹配?_.net_Workflow Foundation - Fatal编程技术网

.net 为什么变量的泛型类型参数必须与设置它的相应OutArgument精确匹配?

.net 为什么变量的泛型类型参数必须与设置它的相应OutArgument精确匹配?,.net,workflow-foundation,.net,Workflow Foundation,考虑以下C代码: public static Foo CreateFoo() { return new Foo(); } // ... public static void Main() { IFoo foo = CreateFoo(); } 相当简单:赋值语句允许目标变量的类型不如表达式的类型具体 因此,我期望注释掉的行能够工作,但由于以下原因,它失败了,迫使任何设置Foo的东西返回具体Foo类的实例,而不仅仅是IFoo: 子活动定义 我想有一个变通方法可以让它看起来像这

考虑以下C代码:

public static Foo CreateFoo()
{
    return new Foo();
}

// ...

public static void Main()
{
    IFoo foo = CreateFoo();
}
相当简单:赋值语句允许目标变量的类型不如表达式的类型具体

因此,我期望注释掉的行能够工作,但由于以下原因,它失败了,迫使任何设置Foo的东西返回具体Foo类的实例,而不仅仅是IFoo:

子活动定义 我想有一个变通方法可以让它看起来像这样:

public static void Run()
{
    IFoo foo;

    Foo uglyWorkaround = TryExistingActivity();
    if (uglyWorkaround == null)
    {
        foo = UseMyShinyNewActivity();
    }
    else
    {
        foo = uglyWorkaround;
    }
}
…这可能就是我最终要做的,尽管我倾向于遵循传统的东西并使用它,作为使单元测试不会失败的魔杖

总结 从根本上说,为什么我不能使用变量来存储活动的OutArgument的结果?或者这仅仅是标准的实施成本与效益之比

编辑1:完全用C语言复制 这使用了上面子活动定义中的相同活动

class Program
{
    static void Main()
    {
        Variable<IFoo> theFoo = new Variable<IFoo>("TheFoo");
        Sequence sequence = new Sequence
                            {
                                Variables =
                                {
                                    theFoo
                                },
                                Activities =
                                {
                                    new ActivityWithOutArgument
                                    {
                                        Result = theFoo
                                    }
                                }
                            };

        // The following fails with:
        // InvalidWorkflowException was Unhandled
        // The following errors were encountered while processing the workflow tree:
        // 'VariableReference<Foo>': Variable 'System.Activities.Variable`1[MyNamespace.IFoo]' cannot be used
        // in an expression of type 'MyNamespace.Foo', since it is of type 'MyNamespace.IFoo' which is not compatible.
        WorkflowInvoker.Invoke(sequence);
    }
}

由于WF的设计方式,输入和输出由泛型类表示,而泛型类不能是协变或逆变的

但是,WF的任何基本要素都不能阻止这一点,因此这是可行的:

使用制度; 使用系统活动; 使用系统、活动、报表; 使用系统、活动、表达式; 命名空间WorkflowConsoleApplication1 { 公共接口IFoo { 虚无点滴; } 公开密封等级Foo:IFoo { public void DoThing=>Console.WriteLineHello; } 不带参数的公共密封类活动:CodeActivity { 受保护的覆盖Foo ExecuteCodeActivityContext=>new Foo; } 内部静态类程序 { 专用静态空干管 { 变量theFoo=新变量name of foo; 序列=新序列 { 变数= { theFoo, }, 活动= { 新分配 { To=theFoo, 值=新类型 { 操作数=不带参数的新活动, }, }, 新方法 { TargetObject=新的InArgumenttheFoo, MethodName=nameofIFoo.DoThing, }, } }; WorkflowInvoker.Invokesequence; } } }
这是一个完全可以用C代码重现的问题吗?@BenAaronson是-请参见编辑1。这个问题的顶部答案是否涵盖了它@不,这只是处理标准的C/.NET类型转换规则。我在这里的基本问题是工作流基础,即编程模型,有它自己的一组独立的关于什么可以被分配给变量的规则,在这种情况下,它与正常的C/Net编程模型中的同类事物混淆不一致。
public static void Run()
{
    IFoo foo = TryExistingActivity();
    if (foo == null)
    {
        foo = UseMyShinyNewActivity();
    }
}
public static void Run()
{
    IFoo foo;

    Foo uglyWorkaround = TryExistingActivity();
    if (uglyWorkaround == null)
    {
        foo = UseMyShinyNewActivity();
    }
    else
    {
        foo = uglyWorkaround;
    }
}
class Program
{
    static void Main()
    {
        Variable<IFoo> theFoo = new Variable<IFoo>("TheFoo");
        Sequence sequence = new Sequence
                            {
                                Variables =
                                {
                                    theFoo
                                },
                                Activities =
                                {
                                    new ActivityWithOutArgument
                                    {
                                        Result = theFoo
                                    }
                                }
                            };

        // The following fails with:
        // InvalidWorkflowException was Unhandled
        // The following errors were encountered while processing the workflow tree:
        // 'VariableReference<Foo>': Variable 'System.Activities.Variable`1[MyNamespace.IFoo]' cannot be used
        // in an expression of type 'MyNamespace.Foo', since it is of type 'MyNamespace.IFoo' which is not compatible.
        WorkflowInvoker.Invoke(sequence);
    }
}