Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
C# 使用模板化参数调用方法_C#_Oop_Templates_Xamarin - Fatal编程技术网

C# 使用模板化参数调用方法

C# 使用模板化参数调用方法,c#,oop,templates,xamarin,C#,Oop,Templates,Xamarin,我有一个通用方法: protected override void Work<T>(T requestResult) { ... CallsSomeOtherMethodFromOtherClass(requestResult); } 请注意,此代码是在没有IDE的情况下编写的,尚未编译。不要复制和粘贴它 您可以做的是向泛型添加约束。所以T继承了X。 在这种情况下,T必须从接口IWorkUnit继承 protected override void Work<T

我有一个通用方法:

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

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

您可以做的是向泛型添加约束。所以T继承了X。 在这种情况下,T必须从接口IWorkUnit继承

protected override void Work<T>(T requestResult) where T : IWorkUnit
{
    DoWork(requestResult);
}
protected override void Work(T requestResult),其中T:i工作单元
{
DoWork(请求结果);
}
然后,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;
    }
}
protected override void Work(T requestResult),其中T:i工作单元
{
开关(requestResult.TypeOfWork){
违约:
案例类型。测试:
DoTestWork(requestResult);
打破
案例EWorkType.Work:
DoWork(请求结果);
打破
}
}
或者,您可以只使用模式匹配。我建议在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;
    }
}
受保护的覆盖无效工作(T requestResult)
{
开关(请求结果){
案例IT测试单元:
DoTestWork(测试单元);
打破
案例字符串workStr:
道具(工作TR);
打破
违约:
//显示错误
打破
}
}

由于
工作
被定义为一种通用方法,编译器无法知道
请求结果
将始终是一个
字符串
。它可以是任何类型的
T

如果您“确定类型
T
将是
字符串
”,那么您最好将该方法定义为非泛型
无效工作(字符串请求结果)
。无论如何,定义一个只接受
字符串的泛型方法是没有意义的

如果由于某种原因无法实现,您可以按照@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);
    }
}
受保护的覆盖无效工作(T requestResult)
{
字符串s=请求结果为字符串;
如果(s!=null)
{
调用OtherClass中的OtherMethods;
}
}

如果您确定T始终是字符串,为什么将该方法定义为泛型方法?编译器不知道t总是一个字符串。@mm8在这个特殊的重写中,我知道它将是一个字符串。但在其他一些覆盖中,它不会!那么,您需要尝试在运行时将requestResult转换为字符串。就编译器而言,requestResult可能是任何类型的T。@mm8我试过了!->工作((字符串)请求结果);但它说它不能在编译时或运行时将T转换为Stringt?你看到我的代码样本了吗。。。?也许你应该试一试。work(…)方法在这个特定的重写中接受一个字符串。但在其他具体的实现中,它将是其他类型的。然后,正如我在回答中所解释的那样,您将不再进行铸造。是的。编译器不喜欢转换:“从t到字符串的不可能转换”以及什么版本的Visual Studio。。。?这显然适合我。请提供所有其他人能够从头开始复制您的问题所需的代码。Thx为您的答案。必须更改doWork()原型才能接受IWorkUnit类型?不?是的,但我的工作单位只是一个例子。如果您希望保持方法的签名完整,可以使用最后一个示例。我很难理解您的案例说明。workStr的值是多少?workStr将被转换为字符串。仅当requestResult可以强制转换为字符串时,才会执行该情况:)
protected override void Work<T>(T requestResult)
{
    string s = requestResult as string;
    if (s != null)
    {
        CallsSomeOtherMethodFromOtherClass(s);
    }
}