繁体   English   中英

C# 有没有更好的方法可以在泛型类型上使用 Switch-Case / If-Else

[英]C# Is there any better way to use Switch-Case / If-Else on generic types

我目前正在尝试对泛型类型进行一些转换。 所以基本的想法是有一个方法,它接受一个泛型类型,并根据传入的类型做不同的事情。

为简单起见,我将只展示floatbooldefault

设置看起来像这样(其中T是类本身定义的泛型类型):

protected T DoStuff(T value)
{
   switch (value) {
      case float floatValue:
         float result = DoFloatStuff(floatValue);
         switch (result) {
            case T output:
               return output;
         }
      case bool boolValue:
         bool result = DoBoolStuff(boolValue);
         switch (result) {
            case T output:
               return output;
         }
      default:
         // return value;
         DoRealGenericStuff(value) // Edited, since I just want to sort out some special cases
   }
}

其中DoFloatStuffDoBoolStuff只是分别具有 1 个参数和它们类型的返回类型的方法。

如果我不那样做(我之前尝试过一些typeof()转换),编译器总是抱怨它不能从Tfloat ,反之亦然,即使我确定某些 Case 会是这种情况- Switch / If-Else 语句。

有没有人知道一些更好的方法来做到这一点?

提前致谢,BOTHLine

编辑:由于很多人都说了同样的话,我要么在这种情况下根本不应该使用泛型,要么我的方法本身需要更通用..我的问题是我需要使用处理我正在检查的特殊情况的第 3 方方法(在这种情况下是floatbool类型)。 对于默认情况,我已经以通用方式处理了所有事情。 但是对于某些定义的类型,我就是做不到这一点。

所以要更详细地说明为什么会这样:我目前正在为“Unity Engine”开发一个插件。 Unity 内置了显示类型的方法(所有原始类型和一些特定于 Unity 的类型)。 我有一个通用的 Wrapper 类,它应该能够包含任何类型。 但是,当我想在 Unity Editor 提供的 GUI 中显示该包装器的内容时​​,我必须使用内置方法来显示基元(类似于UnityEditor.EditrGUI.FloatField() )。 没有这些方法,我永远无法显示任何内容。 然后可以以更通用的方式显示可以分解为这些类型的任何其他内容。

所以基本的想法是有一个方法,它接受一个泛型类型,并根据传入的类型做不同的事情。

那是错误的想法。 这不是应该使用泛型的方式。 在这种情况下,您应该使用方法重载为每种类型单独创建DoStuff

float DoStuff(float value) {/* float implementation here */}
bool DoStuff(bool value) {/* bool implementation here */}
...

泛型的要点是使您能够编写在不同类型上运行相同的代码 - 因此它应该用于类型本身与代码无关的地方(如在任何泛型集合中),或者可以使用接口执行或所有可接受类型实现(或继承)的基类。 此时,泛型通常仅在您希望方法返回接口(或基类)的特定实现时才需要。

让编译器为你整理:

protected void DoStuff(float v){}
protected void DoStuff(int v){}
// and so on
//and finally the default:
protected void DoStuff(object v){}

public void Work(T value)
{
    DoStuff(value)
}

这不是简短的答案,但它是正确的方法(按照许多标准)。 可能有一个简短的答案,但如果我是你,我不会打扰。

这是工厂模式的味道。 泛型应该是,顾名思义,泛型并且对类型无动于衷,如果你可以这样做的话。

interface IDoStuffer<T>
{
    T DoStuff(T value)
}

class DoStuffFloat : IDoStuff<float>
{
    public float DoStuff(float value)
    {
        //Do your float stuff
    }
}

class DoStuffBool : IDoStuff<bool>
{
    public bool DoStuff(bool value)
    {
        //Do your bool stuff
    }
}

然后你可以让一个工厂给你一个正确的实现

class DoStuffFactory
{
    public IDoStuff<T> GetDoStuff<T>()
    {
        if(typeof(T) == typeof(float))
            return new DoStuffFloat();
        //And other types
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM