【发布时间】:2011-03-27 19:33:37
【问题描述】:
我想让 IDictionary<int, Driver> 中的 int 对其含义不那么晦涩,所以我认为将其包装起来可能是个好主意。结果将类似于IDictionary<finishPosition, Driver>。
最好,finishPosition 应该像 finishPosition = 1 这样分配。
我不知道这是否可能以及如何。
【问题讨论】:
我想让 IDictionary<int, Driver> 中的 int 对其含义不那么晦涩,所以我认为将其包装起来可能是个好主意。结果将类似于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)]
【讨论】:
当然,只要使用这个 using 指令:
using FinishPosition = System.Int32;
在源文件的顶部,并像在示例中一样编写代码。
如果您像这样使用 using 指令,FinishPosition 是一个 int,其他文件会将其视为一个 int - 没有定义新类型 FinishPosition(感谢 cmets 中的配置器)。
【讨论】:
FinishPosition 是 一个Int32 并且其他文件会将其视为int。但它不会“隐藏”它或类似的东西......为什么会这样?
using System。 /facepalm :P 我会编辑我的答案。这将教我用 Notepad++ 而不是 VS 编写测试代码。
你可以使用枚举:
enum Position { Finish, Some, Other }
IDictionary<Position, Driver> lookup = ...;
Driver d = lookup[Position.Finish];
【讨论】:
0 或 enum 值,或显式转换。
在我看来,在将通用值用于特定意图的任何地方都可以使用 AbstractDataType 模式(这种情况已由许多其他人提出,例如 Percentage、ReadonlyString、ConnectionString 等)
注意,我个人认为,与它们进行隐式转换有点把整个事情都掏空了(通过隐式转换,编译器不再保证在正确的地方以特定意图使用泛型值) .
下面的示例应该会激发您按照自己的方式进行操作:您仍然可以选择自己喜欢的便利程度/详细程度。它展示了两种方法:
注意事项
事不宜迟:
#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];
}
}
}
【讨论】:
我刚刚在 [1] 之前链接的问题中调整了 RichEnum 通用基类
我想说我更喜欢这种方法,因为从长远来看,它确实看起来最灵活。实际上,我能想到的唯一缺点是 RichEnum 类型不再是值类型。
去看看我的意思(再次包括一个完全运行的示例):
【讨论】: