使用模板化参数调用方法

时间:2017-12-20 13:59:59

标签: c# oop templates xamarin

我有一个通用的方法:

protected override void Work<T>(T requestResult)
{
    ...
    CallsSomeOtherMethodFromOtherClass(requestResult);
}

但是Xamarin不会让我这样做。
它表示它不能将 requestResult 强制转换为字符串( CallsSomeOtherMethodFromOtherClass 将字符串作为参数)。

但是在这个特定的覆盖中,我确信类型T将是一个字符串。

我应该更改编译器以便让我调用该方法:

CallsSomeOtherMethodFromOtherClass(string);

2 个答案:

答案 0 :(得分:0)

请注意,此代码是在没有IDE的情况下编写的,尚未编译。不要复制并粘贴它。

您可以做的是为通用添加约束。所以T继承自X. 在这种情况下,T必须从接口IWorkUnit继承。

protected override void Work<T>(T requestResult) where T : IWorkUnit
{
    DoWork(requestResult);
}

然后DoWork接受IWorkUnit作为参数。 IWorkUnit将包含您可能需要的任何属性。

完整示例:

protected override void Work<T>(T requestResult) where T : IWorkUnit
{
    switch(requestResult.TypeOfWork) {
        default:
        case EWorkType.Test:
            DoTestWork(requestResult);
        break;

        case EWorkType.Work:
            DoWork(requestResult);
        break;
    }
}

或者你可以使用模式匹配。我建议在IWorkUnit中添加一个枚举,它显示了工作单元的工作类型。 然后建立工厂以确定应该使用什么方法来处理请求,如下所示:

protected override void Work<T>(T requestResult)
{
    switch(requestResult) {
        case ITestUnit testUnit:
            DoTestWork(testUnit);
        break;

        case string workStr:
            DoWork(workStr);
        break;

        default:
            //Show error
        break;
    }
}

答案 1 :(得分:0)

由于Work被定义为泛型方法,因此编译器无法知道requestResult将永远是string。它可以是任何类型T

如果您“确定类型T将是string”,您也可以将该方法定义为非通用void Work(string requestResult)。定义一个只接受strings的通用方法是没有意义的。

如果出于某种原因无法做到这一点,您可以尝试按照@Fildor的建议在运行时将requestResult强制转换为string。这是在早期(C#6-)版本的C#和Visual Studio中执行此操作的方法:

protected override void Work<T>(T requestResult)
{
    string s = requestResult as string;
    if (s != null)
    {
        CallsSomeOtherMethodFromOtherClass(s);
    }
}