C#类型安全和开发人员友好列表/收集技术

时间:2010-06-16 15:51:37

标签: c# collections

我正在使用sp调用的结果填充“Dictionary”。键是字段名称,值是sp为字段返回的值。这一切都很好,但出于安全和文档原因,我希望开发人员有一个预定义的密钥列表来访问此列表。我想做的是将枚举作为字典的键,这样开发人员可以安全地访问列表,但仍然能够使用字符串键值访问字典。

我希望有一个字符串值列表,我可以使用枚举键和字符串键访问它。请确保任何建议都易于实现,这不是我愿意为实现构建大量开销的事情。

注意: 我希望有一个键可以驱动这个不是一个枚举声明和一个List声明,因为我将维护两个键列表,只是格式略有不同。

更新: 让我澄清一下我想要一个字符串键的原因,我在一次使用这个列表中的东西来替换一个更大的字符串,其中包含类似## keyName ##的东西。所以我需要能够根据####中的内容从字典中获取值。如果我使用enum作为我的密钥,我不知道该怎么做。如果我可以将字符串“keyName”映射到enum.keyName,那么我的问题就解决了。

8 个答案:

答案 0 :(得分:3)

我只想创建一个包含常量字符串而不是枚举的类。

class Keys
{
    public const string Key1 = "Key1";
    public const string Key2 = "Key2";
}

这样您就不必对字典做任何事情,但仍然有“建议的密钥”。

答案 1 :(得分:1)

任何枚举都可以转换为带ToString的字符串。因此,您可以编写一个索引器,它接受任何对象并在其上调用ToString。对于字符串,这是一个无操作。

修改

从meiscooldude窃取一个想法:

public static class EnumDictExt
{
    public static TValue Lookup<TValue, TEnum>(this IDictionary<string, TValue> dict, TEnum e)
            where TEnum : struct, IComparable, IFormattable, IConvertible
        { return dict[e.ToString()]; }
}

答案 2 :(得分:1)

如果您没有寻找大量开销,那么使用扩展方法是可能的。

答案 3 :(得分:1)

听起来您正在尝试复制已存在于类型化数据集,LINQ to SQL或甚至普通旧DTO中的功能(可能在Automapper的帮助下)。开发人员会发现使用已熟悉的结构(如数据表或对象属性)更容易使用

答案 4 :(得分:0)

您可以将Dictionary包装在自定义类中,并为该类添加两个索引器,一个用于字符串访问,另一个用于枚举访问

答案 5 :(得分:0)

您可以尝试以下内容:

public enum MyKeys
{
    FirstKey,
    SecondKey,
    ThirdKey
}

然后在你的代码的其他地方:

var dict = new Dictionary<MyKeys, string>();

dict.Add(MyKeys.FirstKey, "something");
dict.Add(MyKeys.SecondKey, "something else");
dict.Add(MyKeys.ThirdKey, "something else again");

// And then to access them, you can use
var stringVal = dict[MyKeys.FirstKey];
var secondVal = dict[(MyKeys)Enum.Parse(typeof(MyKeys), "secondkey", true)];

答案 6 :(得分:0)

像其他人说的那样,你可以创建两个索引器。但是为了鼓励枚举和不鼓励字符串,使枚举成为索引器,并将字符串api命名为“GetTheValueOfThisElementWhichCanBeUnsafe”或类似名称(你明白了......)。

像我一样懒惰,如果两者都是索引器我不在乎,但一直使用字符串版本。但如果API以某种方式对我咆哮,我至少会看到代码中的含义。

答案 7 :(得分:0)

如果我理解正确的话,我最近做了一些类似于从服务器接收/发送到服务器的数据包。数据包的格式为Key: Value\n,并由一个特殊的键/值对定义,表示其数据包类型(Action: Login,在本例中如下。请参阅Asterisk API以获取更多参考。)我解析了数据包类型输出,基于预期的键生成类,如下:

public abstract class Packet
{
    private Dictionary<string, string> _dictionary =
        new Dictionary<string, string>();

    public string this[string key]
    {
        get
        {
            if (_dictionary.ContainsKey(key))
            {
                return _dictionary[key];
            }
            else { return ""; }
        }
        set { _dictionary[key] = value; }
    }

    public abstract PacketType Type { get; }
}

public class LoginPacket : Packet
{
    public override PacketType Type
    { get { return PacketType.Action; } }

    public string Username
    {
        get { return this["Username"]; }
        set { this["Username"] = value; }
    }
    public string Password
    {
        get { return this["Password"]; }
        set { this["Password"] = value; }
    }
    public int Status // Example: Not an actual key in Login in the Asterisk API
    {
        get { return int.Parse(this["Status"]); }
        set { this["Status"] = value.ToString(); }
    }
}

这会创建一种强类型字典,您可以这样做:

LoginPacket packet = new LoginPacket
{
    Username = "User",
    Password = "user",
    Status = 123
};
Console.WriteLine(packet.Username); // Is equal to:
Console.WriteLine(packet["Username"]);

然后像任何其他类字典类一样处理packet,你可以扩展这个,以便Packet实现IDictionary,或者转向另一个方向,使this[string key] get或{ {1}}受保护,以便仅使用 有效密钥。