Take the 2-minute tour ×

I want to make the int in IDictionary<int, Driver> a little less obscure about its meaning, so I thought maybe wrapping it would be a good idea. The outcome would be something like IDictionary<finishPosition, Driver>.

Preferably, finishPosition should be assignable like this finishPosition = 1.

I do not know if this is possible and how.

share|improve this question
add comment

5 Answers

up vote 4 down vote accepted

You could use a struct with an implicit conversion.

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)]
share|improve this answer
This is clearly a better solution than mine. Less confusing by far. –  Martin Doms Mar 27 '11 at 20:51
Seems correct and what was asked, but it's quite a bit of overhead... And for readability (and safety) I would omit the implicit conversion. –  Henk Holterman Mar 27 '11 at 21:38
@Henk: The entire point of this is the implicit conversion; it doesn't hurt readability as much as you would think when it only works one way. –  configurator Mar 27 '11 at 21:44
@Config: Yes, it was asked for. But it does eat directly into the readability. A conflict in the question. –  Henk Holterman Mar 27 '11 at 21:46
@Henk: it's true that implicit casts actively hurt readability in some cases, but they also help in other cases. For example, if you have implicit casts in both ways it's sometimes very confusing. But for wrappers like this it's extremely convenient and doesn't reduce readability in any way. –  configurator Mar 27 '11 at 21:49
show 1 more comment

Absolutely, just use this using directive:

using FinishPosition = System.Int32;

at the top of your source file, and write the code just as you have in your example.

If you use the using directive like this, FinishPosition is an int and other files will see it as an int - there is no new type FinishPosition defined (thanks for configurator in the comments).

share|improve this answer
Awesome! Do you know if there is an equivalent in VB.NET for this trick? –  Maxim Gershkovich Mar 27 '11 at 20:20
Just tried it and it works in VB.NET too. Imports myValue = System.Int32 –  Maxim Gershkovich Mar 27 '11 at 20:21
Erm... No it doesn't. The problem may be that FinishPosition is an Int32 and other files will see it as an int. But it doesn't "hide" it or anything like that... Why would it? –  configurator Mar 27 '11 at 20:25
Haha ok that's only because I was missing using System. /facepalm :P I'll edit my answer. That'll teach me to write test code in Notepad++ instead of VS. –  Martin Doms Mar 27 '11 at 20:38
That's a potentially confusing way of doing it. It's still an int. Any documentation will say it's an it (it's simply called so Else in the source file. The information is completely gone when compiling and intellisense in different files shoul report it As int. The syntax is meant for disambiguation –  Rune FS Mar 27 '11 at 20:48
show 10 more comments

You could use an enum:

enum Position { Finish, Some, Other }

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

Driver d = lookup[Position.Finish];
share|improve this answer
Maybe I understand you wrong (or the other way around) - But the finishPosition should be assignable with different kinds of integer, like finishPosition = 1, finishPosition = 2, finishPosition = 3, and assign each of these with a Driver object for that position - and storing these in the dictionary. the dictionary will be drivers and the positions they finished in. –  Garth Marenghi Mar 27 '11 at 19:53
Best thing is to name those integers (Some, Other) but you can also assign an arbitrary int value. Maybe I got your naming wrong though, adapt. –  Henk Holterman Mar 27 '11 at 19:58
You can't assign arbitrary integers to an enum variable. Only 0 or an enum value, or with explicit casting. –  configurator Mar 27 '11 at 20:26
@config: Yes on the explicit cast. –  Henk Holterman Mar 27 '11 at 21:33
Thanks for your answer, though I'm still trying to wrap my head around it :-) –  Garth Marenghi Mar 28 '11 at 6:36
add comment

In my opinion, it is good to use AbstractDataType pattern anywhere where a general value is used with specific intents (this case has been made by many others with examples like Percentage, ReadonlyString, ConnectionString, etc.)

Note, I personally think that having implicit conversions to and from them sort of hollows the whole thing out (by having an implicit conversion, there is no more compiler guarantee that generic values are being used with specific intent at the right place).

Here is a sample that should inspire you to have it your way: you can still choose the level of convenience/verbosity you prefer. It show two approaches:

  • _byInt indexes a dictionary by PseudoInt
  • _byEnum indexes a dictionary by an Enum : int type


Without further ado:

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; }
        public static implicit operator T(Pseudo<T> pi)  { return pi.Value; }
        public static implicit operator Pseudo<T>(T ni)  { return new Pseudo<T>(ni); }

    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];
share|improve this answer
Thanks for your answer! –  Garth Marenghi Mar 28 '11 at 6:32
add comment

I just adapted the RichEnum generic baseclass in the question I linked before [1]

I'd say I prefer this method because it really seems the most flexible in the long run. The only downside I can think of, really, is that the RichEnum type cannot be a value type anymore.

Head over to see what I mean (includes a fully running sample again):

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

share|improve this answer
add comment

Your Answer


