我想让IDictionary<int, Driver>
中的整数在它的意义上稍微模糊一点,所以我想也许包装它会是一个好主意。结果将如IDictionary<finishPosition, Driver>
。是否可以包装整数并将其称为整数?
优选地,finishPosition应该可以像这样分配finishPosition = 1
。
我不知道这是可能的以及如何。
我想让IDictionary<int, Driver>
中的整数在它的意义上稍微模糊一点,所以我想也许包装它会是一个好主意。结果将如IDictionary<finishPosition, Driver>
。是否可以包装整数并将其称为整数?
优选地,finishPosition应该可以像这样分配finishPosition = 1
。
我不知道这是可能的以及如何。
您可以使用带有隐式转换的struct
。
public struct FinishPosition {
public readonly int Position;
public FinishPosition(int position) {
this.Position = position;
}
public static implicit operator FinishPosition(int position) {
return new FinishPosition(position);
}
}
// ...
Dictionary<FinishPosition, Driver> dict = new Dictionary<FinishPosition, Driver>();
Driver bob = new Driver();
// The following two lines are effectively equivalent
dict[new FinishPosition(7)] = bob;
dict[7] = bob;
// So are these two
bob = dict[7];
bob = dict[new FinishPosition(7)]
你可以使用一个枚举:
enum Position { Finish, Some, Other }
IDictionary<Position, Driver> lookup = ...;
Driver d = lookup[Position.Finish];
也许我明白你错了(或者反过来) - 但finishPosition应分配使用不同种类的整数,如finishPosition = 1,finishPosition = 2,finishPosition = 3,并为每个这些对象分配一个Driver对象 - 并将它们存储在字典中。字典将是驱动程序和他们完成的位置。 – 2011-03-27 19:53:45
最好的办法是命名这些整数(Some,Other),但也可以指定任意的int值。也许我的命名错误了,请适应。 – 2011-03-27 19:58:00
您不能将任意整数赋值给枚举变量。只有'0'或'enum'值,或者有明确的转换。 – configurator 2011-03-27 20:26:48
绝对的,只是用这个using指令:
using FinishPosition = System.Int32;
在你的源文件的顶部,并编写代码,就像你有在你的例子中。
如果你这样使用using指令,FinishPosition是一个int,其他文件将会把它看作一个int - 没有定义新的FinishPosition类型(感谢评论中的配置器)。
太棒了!你知道在VB.NET中是否有这个技巧的等价物? – 2011-03-27 20:20:11
刚刚尝试过,它也适用于VB.NET。导入myValue = System.Int32 – 2011-03-27 20:21:46
这看起来像一个疯狂的C技巧。 +1 – 2011-03-27 20:24:24
在我看来,在一般的值与特定的意图使用(这种情况下,已经取得了许多人喜欢用百分比,ReadonlyString,ConnectionString的实例等)
这是很好的任何地方使用AbstractDataType模式请注意,我个人认为,通过隐式转换可以让整个事情变得空洞(通过隐式转换,没有更多的编译器保证通用值在特定位置与正确的位置一起使用) 。
下面是一个应该鼓励您按照自己的方式使用的示例:您仍然可以选择您喜欢的便利/详细程度。这表明两种方法:
注
事不宜迟:
#define IMPLICIT_CONVERSIONS
using System.Collections.Generic;
namespace NS
{
public enum PositionEnum : int { Begin = 0, Normal = 1, End = 99 }
public struct Pseudo<T> where T : struct
{
public T Value;
public Pseudo(T value) { Value = value; }
#if IMPLICIT_CONVERSIONS
public static implicit operator T(Pseudo<T> pi) { return pi.Value; }
public static implicit operator Pseudo<T>(T ni) { return new Pseudo<T>(ni); }
#endif
}
static class Program
{
private static Pseudo<T> AsPseudo<T>(this T value) where T : struct
{
return new Pseudo<T>(value);
}
private static readonly IDictionary<Pseudo<int>, string> _byInt =
new Dictionary<Pseudo<int>, string>()
{ { 0, "aap" },
{ 1, "noot" },
{ 99, "mies" },
};
private static readonly IDictionary<Pseudo<PositionEnum>, string> _byEnum =
new Dictionary<Pseudo<PositionEnum>, string>()
{ { PositionEnum.Begin, "aap" },
{ PositionEnum.Normal, "noot" },
{ PositionEnum.End, "mies" },
};
public static void Main(string[] args)
{
string s;
s = _byInt[0];
s = _byEnum[PositionEnum.Normal];
}
}
}
感谢您的回答! – 2011-03-28 06:32:20
我刚刚适应了在我之前链接的问题中的RichEnum泛型基类[1]
我想说我更喜欢这种方法,因为它从长远来看似乎是最灵活的。唯一不足的是我能想到的是,RichEnum类型不再是一个值类型。
头以上明白我的意思(也包括完全运行示例):
这显然是比我更好的解决方案。 – 2011-03-27 20:51:43
似乎是正确的,问了什么,但它的开销是相当大的......为了可读性(和安全性),我将省略隐式转换 – 2011-03-27 21:38:07
@亨克:这是整个转换的隐含点,它不会不会伤害到可读性,就像你认为只有一种方式一样。 – configurator 2011-03-27 21:44:04