2

我需要一种将过滤器添加到页面的方法,如下所示:

目录/尺寸-中/颜色-红色/

我有一定数量的过滤器,它们包含不太可能很快改变的属性。为了处理这些过滤器,我决定使用枚举,但这变得非常阴险,因为我需要合并空值、扩展方法和其他属性。

最后我遇到了这个建议使用结构的Stackoverflow 答案。这是我合并的一个示例:

    public struct Color
{
    private int id;
    private bool isDef;

    private Color(int value) { id = value; isDef = true; }
    public bool Hasvalue { get { return isDef; } }
    public bool IsNull { get { return !isDef; } }

    public string Name
    {
        get
        {
            switch(id)
            {
                case 0: return "None";
                case 1: return "Black";
                case 2: return "Blue";
                case 3: return "Green";
                case 4: return "Orange";
                case 5: return "Pink";
                case 6: return "Brown";
                case 7: return "White";
                case 8: return "Yellow";
                case 9: return "Gray";
                case 10: return "Purple";
                case 11: return "Red";
                default: return null;
            }
        }
    }

    public string Abbreviation
    {
        get
        {
            switch(id)
            {
                case 1: return "BK";
                case 2: return "BL";
                case 3: return "GR";
                case 4: return "OR";
                case 5: return "PK";
                case 6: return "BN";
                case 7: return "WT";
                case 8: return "YL";
                case 9: return "GY";
                case 10: return "PR";
                case 11: return "RD";
                default: return null;
            }
        }
    }

    public static IEnumerable<Color> GetValues()
    {
        yield return Color.None;
        yield return Color.Black;
        yield return Color.Blue;
        yield return Color.Green;
        yield return Color.Orange;
        yield return Color.Pink;
        yield return Color.Brown;
        yield return Color.White;
        yield return Color.Yellow;
        yield return Color.Gray;
        yield return Color.Purple;
        yield return Color.Red;
    }

    public static Color Parse(string value)
    {
        if (String.IsNullOrEmpty(value))
            return Color.None;
        foreach (var c in GetValues())
        {
            if (String.Equals(c.Name, value, StringComparison.Ordinal))
                return c;
        }
        return Color.None;
    }

    public override bool Equals(object obj)
    {
        if(!(obj is Color))
            return false;
        Color color = (Color)obj;
        return color.Name.Equals(this.Name, StringComparison.Ordinal);
    }

    public static Color None = new Color(0);
    public static Color Black = new Color(1);
    public static Color Blue = new Color(2);
    public static Color Green = new Color(3);
    public static Color Orange = new Color(4);
    public static Color Pink = new Color(5);
    public static Color Brown = new Color(6);
    public static Color White = new Color(7);
    public static Color Yellow = new Color(8);
    public static Color Gray = new Color(9);
    public static Color Purple = new Color(10);
    public static Color Red = new Color(11);
}

这些工作很好,但他们只是在某些方面感觉不正确。例如,我必须为每个结构编写相同的代码,这看起来像是很多代码。继承可重用代码并以某种方式将数据限制为接口会容易得多。

有没有更好的方法来做到这一点?我尝试过使用静态类,但不知道如何构建一个与我的结构具有相似功能的类。

抱歉,如果我在发帖时似乎没有希望,这是我的第一次。

4

1 回答 1

3

你需要一个颜色的枚举和一个 apprev-color 映射的字典

从正确的类导入开始:

using System.Collections.Generic;

创建一个包含所有可能颜色的枚举:

enum Colors : uint 
{
  Black =  0x00000000,
  Blue =   0x0000FF00,
  Green =  0x00FF0000,
  Orange = 0xFFA50000,
  Pink =   0xFFC0CB00,
  Brown =  0xA52A2A00,
  White =  0xFFFFFF00,
  Yellow = 0xFFFF0000,
  Gray =   0x80808000,
  Purple = 0x80008000,
  Red =    0xFF000000
};

注意:这是假设 RGBA [rrggbbaa] 其中或 Red|Green|Blue|Alpha 可以是 00-FF (0-255) 之间的任何值。

然后使用字典来映射颜色值的一对多关系:

private Dictionary<string, Colors> colorMap = new Dictionary<string, Colors>();
colorMap.Add("None", Colors.None);
colorMap.Add("Black", Colors.Black);
colorMap.Add("BK", Colors.Black);
colorMap.Add("Blue", Colors.Blue);
colorMap.Add("BL", Colors.Blue);
colorMap.Add("Green", Colors.Green);
colorMap.Add("GR", Colors.Green);
colorMap.Add("Orange", Colors.Orange);
colorMap.Add("OR", Colors.Orange);
colorMap.Add("Pink", Colors.Pink);
colorMap.Add("PK", Colors.Pink);
colorMap.Add("Brown", Colors.Brown);
colorMap.Add("BN", Colors.Brown);
colorMap.Add("White", Colors.White);
colorMap.Add("WT", Colors.White);
colorMap.Add("Yellow", Colors.Yellow);
colorMap.Add("YL", Colors.Yellow);
colorMap.Add("Gray", Colors.Gray);
colorMap.Add("Grey", Colors.Gray);
colorMap.Add("GY", Colors.Gray);
colorMap.Add("Purple", Colors.Purple);
colorMap.Add("PR", Colors.Purple);
colorMap.Add("Red", Colors.Red);
colorMap.Add("RD", Colors.Red);

以及映射的字典查找方法:

public Color GetColor(string colorName)
{
  Color color = null;
  if (this.colormap.TryGetValue(colorName, out color));
  return color;
}

注意:不能使用属性,因为您的输入和输出类型不同。

TryGetValue()进行字典查找。TryGetValue() 比 GetValue() 更受欢迎,因为如果它找不到密钥,它什么也不做(默认为您最初将“颜色”设置为的任何值。替代方法 (GetValue()) 会在失败时引发异常,需要被抓住。

奖金:

我在映射中添加了另一个值,看看你能不能找到它。映射值的好处是,它是可扩展的(易于添加)。你不会把自己锁在一个脆弱的结构中。

免责声明:

我在大约一年内没有写过一行 C#,所以这段代码可能不会像发布的那样工作。希望如果有任何错误,我在传达我的意思的要点方面做得很好。

更新:

我决定将 RGBA 值添加到枚举中。如果您还不知道,默认情况下,枚举的核心就像一个“字典”,其中 int 是自动生成的。通过更改它的类型并定义值,它可以转换为可用值(在本例中为“字典”)。

从枚举值中获取颜色名称就像转换它一样简单:

string colorName = "Gray";
Colors color = GetColor(colorName);
if(colorName != null)
{
  uint colorHex = (uint)color;
}

注意:我会打印 colorHex 但没有正确的格式它只会显示整数值(即不是十六进制值)。我不记得如何在头顶上进行文本格式化,所以我不会打扰。如果其他人想添加字符串格式,我不会反对。

更新 2:反向查找

public string GetAbbrev(Colors color)
{
  Dictionary<string, Colors> abbrev = this.colorMap.First(abbrev => abbrev.Value == color);
  return abbrev.Key;
}

我认为这种方法应该适用于反向查找。如果您不了解 LINQ 语法,它会查询所有字典条目并返回键与方法参数匹配的第一个条目。然后从该条目返回密钥。

于 2012-04-20T22:28:53.283 回答