You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中C#字符串与枚举比较及自定义Contains实现咨询

完美解决枚举与字符串关联的Contains检测问题

哈哈,这个需求我太熟了!C#枚举确实没法直接给成员赋值字符串,但咱们可以用特性+扩展方法的组合来实现你的目标——让字符串的Contains方法直接接收枚举成员,自动映射到对应的字符串去检测,完全不用手动写字符串常量!

我给你拆解成一步步的实现方案,直接套到你的Unity代码里就行:

步骤1:定义绑定字符串的自定义特性

首先咱们需要一个特性类,用来给每个枚举成员“挂”上对应的字符串值:

using System;

// 自定义特性,用来存储枚举对应的字符串值
[AttributeUsage(AttributeTargets.Field)]
public class StringValueAttribute : Attribute
{
    public string Value { get; }

    public StringValueAttribute(string value)
    {
        Value = value;
    }
}

步骤2:给你的BeadColor枚举加上特性

现在把你想要的字符串值绑定到枚举成员上:

public enum BeadColor
{
    [StringValue("P")]
    BLUE,
    [StringValue("B")]
    RED,
    // 这里可以继续加其他枚举成员和对应的字符串
}

步骤3:写枚举的扩展方法,获取对应的字符串

接下来写一个静态扩展方法,帮我们把枚举成员转换成对应的字符串:

using System.Reflection;

public static class EnumExtensions
{
    // 获取枚举成员绑定的字符串值
    public static string GetStringValue(this Enum enumValue)
    {
        // 获取枚举成员的FieldInfo
        FieldInfo fieldInfo = enumValue.GetType().GetField(enumValue.ToString());
        
        // 获取特性
        StringValueAttribute attribute = fieldInfo.GetCustomAttribute<StringValueAttribute>();
        
        // 如果没有加特性,这里可以抛出异常或者返回默认值,根据你的需求调整
        if (attribute == null)
            throw new InvalidOperationException($"枚举成员 {enumValue} 未绑定字符串值");
        
        return attribute.Value;
    }
}

步骤4:给string写扩展方法,支持枚举参数的Contains

这就是你要的核心功能了——让string的Contains能直接接收枚举:

public static class StringExtensions
{
    // 扩展string的Contains方法,支持传入BeadColor枚举
    public static bool Contains(this string source, BeadColor beadColor)
    {
        // 先把枚举转成对应的字符串,再调用原生Contains
        if (string.IsNullOrEmpty(source))
            return false;
        
        string targetString = beadColor.GetStringValue();
        return source.Contains(targetString);
    }
}

步骤5:结合你的现有代码使用

现在回到你的CustomClass和MainClass,调用起来就跟你想的一样简单:

你的CustomClass示例(调整后)

public class CustomClass
{
    public string BigRoadData { get; private set; }
    private readonly string[] strData = { "P", "B", "P", "P", "B" };

    public CustomClass()
    {
        // 构建BigRoadData的逻辑不变
        BigRoadData = string.Join("", strData);
    }
}

MainClass里的调用

public class MainClass
{
    public void Test()
    {
        CustomClass custom = new CustomClass();
        
        // 直接传入枚举成员,检测是否包含对应的字符串
        bool hasBlue = custom.BigRoadData.Contains(BeadColor.BLUE); // 会返回true,因为BigRoadData里有"P"
        bool hasRed = custom.BigRoadData.Contains(BeadColor.RED); // 也会返回true,因为有"B"
        
        Debug.Log($"包含蓝色珠子对应的字符串:{hasBlue}");
        Debug.Log($"包含红色珠子对应的字符串:{hasRed}");
    }
}

一些小提醒

  • 如果你怕有些枚举成员忘记加特性,可以在GetStringValue里返回枚举的ToString()作为 fallback,而不是抛出异常,根据你的业务需求调整就行。
  • 扩展方法要放在静态类里,并且命名空间要能被你的Unity脚本访问到(比如放在全局命名空间,或者你项目常用的命名空间下)。
  • 如果需要忽略大小写的检测,可以在扩展方法里调用source.IndexOf(targetString, StringComparison.OrdinalIgnoreCase) >= 0来替代原生的Contains。

这样一来,你就完全不用直接写字符串常量了,所有的映射都通过枚举和特性来管理,代码可读性和可维护性都高了不少!

内容的提问来源于stack exchange,提问作者Ginxxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:38:10