c# - 我应该使用静态类还是结构以外的其他东西?

标签 c# model-view-controller static filter struct

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

Catalog/Size-Medium/Color-Red/

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

最后我发现了这个Stackoverflow answer建议使用结构。以下是我合并的一个示例:

    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);
}

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

有更好的方法吗?我尝试过使用静态类,但无法理解如何构建一个与我的结构具有类似功能的静态类。

抱歉,如果我在发帖时看起来毫无希望,这是我第一次。

最佳答案

您需要一个颜色枚举和一个用于 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() 更受欢迎,因为如果它找不到 key ,它不会执行任何操作(默认为您最初设置“颜色”的值)。替代方法 (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 语法,它会查询所有字典条目并返回键与方法参数匹配的第一个条目。然后从该条目返回 key 。

关于c# - 我应该使用静态类还是结构以外的其他东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10253950/

相关文章:

ios - 从 TableView 中的按钮创建菜单下拉菜单

ios - 在 UITableViewCell 中显示复杂数据

localization - 如何本地化静态网站?

c++ - 对静态变量和静态方法的 undefined reference

C# WPF - 任务与多线程,以及从中更新 UI 组件

c# - 派生静态成员

ios - 从 AppDelegate 通知 View Controller 的正确方法是什么?

java - 对于生成的 pdf 文件,静态图像不会与 Flying Saucer 和 thymeleaf 一起显示

c# - 在 Silverlight 中重新抛出异常时保留堆栈跟踪

c# - 在将null传递给C#中的函数时,消除歧义