如何改进c#中枚举标识的方法重载结构

本文关键字:方法 重载 结构 标识 枚举 何改进 | 更新日期: 2023-09-27 18:07:13

我有一个结构体,作为动画和声音的容器。

    public struct BambooSounds{
    public Bamboo type;
    public AudioClip sound;
    public string animation;
}

Bamboo在本例中是一个枚举,我可以通过它识别BambooSounds数组中的条目。

这些是获取相应动画和声音的方法头

public string BambooAnimation(Bamboo animation)
public AudioClip BambooSound(Bamboo sound)

问题是我需要为每个新的枚举重新实现这些方法,因为我不能覆盖这些方法,但是我使用它们的模式没有改变(结构体,该结构体的数组,返回数组结构体内容的方法)。

我如何改进这一点,这样我就有了类型安全性和简单的可用性,并且只需要实现一次逻辑。尝试使用泛型方法,但我被困在这一点上,泛型参数需要转换为具体类型,以便我可以将它的值与结构项进行比较。

注::我绝对想保留结构体,或者一个类,因为在Unity中,这些都显示在检查器中,可以不需要编码就可以配置。

如何改进c#中枚举标识的方法重载结构

如果我理解你的问题正确,你想建立一个函数,可以得到所有枚举类型。例如,我们有两个枚举:

public enum Enum1
{
    Test
}
public enum Enum2
{
    Test2
}

这是一个泛型函数:

static void TestEnum<T>(T enumType) where T : struct
        {
            if (enumType is Enum1)
            {
                Console.WriteLine("Enum1");
            }
            if (enumType is Enum2)
            {
                Console.WriteLine("Enum2");
            }
        }

你可以这样调用它:

TestEnum<Enum1>(Enum1.Test);
TestEnum<Enum2>(Enum2.Test2);

这里有三种解决方案:

  1. 手工编写所有的方法。
  2. 泛型方法中的测试类型,如@Kram的回答。
  3. 使用T4模板

第一个显然是令人讨厌的。虽然它最终会得到正确的结果,但根据enum参数的可能数量,我可能只是处理它(可能在我第一次编码它时使用某种脚本)。

第二种方法的缺点是不能提供完整的编译时类型安全,但它可以工作,并且在性能上可以合理地工作。它仍然包含大量的手动重复。

T4模板可能很简单:

<#@ template language="C#" #>
<#@ output extension=".gen.cs" #>
using System;
namespace SomeNamespace
{
  public partial struct BambooSounds
  {
  <#foreach(var type in new []{"Bamboo", "Wood", "Metal", "Whatever"};){#>
    public string <#=type#>Animation(<#=type#> animation)
    {
      // Implementation
    }
    public AudioClip <#=type#>Sound(<#=type#> sound)
    {
      // Implementation
    }
    public void ThisMethodOverloadsToShowThatCanBeDoneToo(<#=type#> thing)
    {
      // Implementation
    }
  <#}#>
  }
}

struct作为partial意味着您可以在正常的。cs文件中拥有大部分定义,这往往更容易使用,并且T4仅生成您需要处理的代码。

虽然T4不像普通代码那样好使用(IDE支持较差),但可以非常快速地产生大量重载。