使用模板参数调用方法

问题描述 投票:2回答:2

我有一个通用的方法:

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

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

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

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

CallsSomeOtherMethodFromOtherClass(string);
c# oop templates xamarin
2个回答
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);
    }
}

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.