2011-03-27 25 views
6

我想让IDictionary<int, Driver>中的整数在它的意义上稍微模糊一点,所以我想也许包装它会是一个好主意。结果将如IDictionary<finishPosition, Driver>是否可以包装整数并将其称为整数?

优选地,finishPosition应该可以像这样分配finishPosition = 1

我不知道这是可能的以及如何。

回答

5

您可以使用带有隐式转换的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)] 
+0

这显然是比我更好的解决方案。 – 2011-03-27 20:51:43

+0

似乎是正确的,问了什么,但它的开销是相当大的......为了可读性(和安全性),我将省略隐式转换 – 2011-03-27 21:38:07

+0

@亨克:这是整个转换的隐含点,它不会不会伤害到可读性,就像你认为只有一种方式一样。 – configurator 2011-03-27 21:44:04

1

你可以使用一个枚举:

enum Position { Finish, Some, Other } 

IDictionary<Position, Driver> lookup = ...; 

Driver d = lookup[Position.Finish]; 
+0

也许我明白你错了(或者反过来) - 但finishPosition应分配使用不同种类的整数,如finishPosition = 1,finishPosition = 2,finishPosition = 3,并为每个这些对象分配一个Driver对象 - 并将它们存储在字典中。字典将是驱动程序和他们完成的位置。 – 2011-03-27 19:53:45

+0

最好的办法是命名这些整数(Some,Other),但也可以指定任意的int值。也许我的命名错误了,请适应。 – 2011-03-27 19:58:00

+0

您不能将任意整数赋值给枚举变量。只有'0'或'enum'值,或者有明确的转换。 – configurator 2011-03-27 20:26:48

5

绝对的,只是用这个using指令:

using FinishPosition = System.Int32;

在你的源文件的顶部,并编写代码,就像你有在你的例子中。

如果你这样使用using指令,FinishPosition是一个int,其他文件将会把它看作一个int - 没有定义新的FinishPosition类型(感谢评论中的配置器)。

+0

太棒了!你知道在VB.NET中是否有这个技巧的等价物? – 2011-03-27 20:20:11

+0

刚刚尝试过,它也适用于VB.NET。导入myValue = System.Int32 – 2011-03-27 20:21:46

+0

这看起来像一个疯狂的C技巧。 +1 – 2011-03-27 20:24:24

1

在我看来,在一般的值与特定的意图使用(这种情况下,已经取得了许多人喜欢用百分比,ReadonlyString,ConnectionString的实例等)

这是很好的任何地方使用AbstractDataType模式

请注意,我个人认为,通过隐式转换可以让整个事情变得空洞(通过隐式转换,没有更多的编译器保证通用值在特定位置与正确的位置一起使用) 。

下面是一个应该鼓励您按照自己的方式使用的示例:您仍然可以选择您喜欢的便利/详细程度。这表明两种方法:

  • _byInt指数一本词典PseudoInt
  • _byEnum指数一本词典的枚举:整型

事不宜迟:

#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]; 
     } 
    } 
} 
+0

感谢您的回答! – 2011-03-28 06:32:20

0

我刚刚适应了在我之前链接的问题中的RichEnum泛型基类[1]

我想说我更喜欢这种方法,因为它从长远来看似乎是最灵活的。唯一不足的是我能想到的是,RichEnum类型不再是一个值类型。

头以上明白我的意思(也包括完全运行示例):

[1] Can we define implicit conversions of enums in c#?

相关问题