Although roman numerals sneak in our lives from time to time, we(luckily) don't use them very often. Probably the reason why the Romans where not that good at calculating things. That changed, more than 1000 years later, with this person who introduced to the Western world the number system we all use today.
But let's come to the point: this is not about a conversion but about the ways to do it.
I don't even refer to the algoritm used, but C# seems to become such a rich expressive language that I'm beginning to have trouble choosing a way to do things. Are ther still other, even better ways to do this? Please let me know.
Any comment on my code is very much appriciated. :)

Thanks to nick.crane (see http://www.daniweb.com/software-development/csharp/threads/376347) who gave me the idea to try it the tuple way.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RomanDigits
{
    class RomanNumeralConverter
    {
        // Way one
        private struct RomanDigit
        {
            public string Rstr;
            public int value;
        }
        private RomanDigit[] Rom;

        // Way two
        private Dictionary<string, int> Roman;

        // Way three
        private List<Tuple<string, int>> ConvTable = new List<Tuple<string, int>>();       
           
        public RomanNumeralConverter() //construct and init  the 3 types
        {
            Rom = new RomanDigit[] 
            { 
                new RomanDigit{Rstr = "M",  value = 1000},
                new RomanDigit{Rstr = "CM", value = 900},
                new RomanDigit{Rstr = "D",  value = 500},
                new RomanDigit{Rstr = "CD", value = 400},
                new RomanDigit{Rstr = "C",  value = 100},
                new RomanDigit{Rstr = "XC", value = 90},
                new RomanDigit{Rstr = "L",  value = 50},
                new RomanDigit{Rstr = "XL", value = 40},
                new RomanDigit{Rstr = "X",  value = 10},
                new RomanDigit{Rstr = "IX", value = 9},
                new RomanDigit{Rstr = "V",  value = 5},
                new RomanDigit{Rstr = "IV", value = 4},
                new RomanDigit{Rstr = "I",  value = 1},
            };

            Roman = new Dictionary<string, int>();           
            Roman.Add("M", 1000);
            Roman.Add("CM", 900);
            Roman.Add("D", 500);
            Roman.Add("CD", 400);
            Roman.Add("C", 100);
            Roman.Add("XC", 90);
            Roman.Add("L", 50);
            Roman.Add("XL", 40);
            Roman.Add("X", 10);
            Roman.Add("IX", 9);
            Roman.Add("V", 5);
            Roman.Add("IV", 4);
            Roman.Add("I", 1);

            ConvTable = new List<Tuple<string, int>>();
            ConvTable.Add(Tuple.Create("M", 1000));
            ConvTable.Add(Tuple.Create("CM", 900));
            ConvTable.Add(Tuple.Create("D", 500));
            ConvTable.Add(Tuple.Create("CD", 400));
            ConvTable.Add(Tuple.Create("C", 100));
            ConvTable.Add(Tuple.Create("XC", 90));
            ConvTable.Add(Tuple.Create("L", 50));
            ConvTable.Add(Tuple.Create("XL", 40));
            ConvTable.Add(Tuple.Create("X", 10));
            ConvTable.Add(Tuple.Create("IX", 9));
            ConvTable.Add(Tuple.Create("V", 5));
            ConvTable.Add(Tuple.Create("IV", 4));
            ConvTable.Add(Tuple.Create("I", 1));
        }

        public string ConvertwithStruct(int Number)
        {
            string RomanStr = string.Empty;
            for (int i = 0; Number > 0; i++)
            {
                while (Rom[i].value <= Number)
                {
                    RomanStr += Rom[i].Rstr;
                    Number -= Rom[i].value;
                }
            }
            return RomanStr;
        }

        public string ConvertwithDict(int Number)
        {
            string RomanStr = string.Empty;
            for (int i = 0; Number > 0; i++)
            {
                while (Roman.ElementAt(i).Value <= Number)
                {
                    RomanStr += Roman.ElementAt(i).Key;
                    Number -= Roman.ElementAt(i).Value;
                }
            }
            return RomanStr;
        }

        public string ConvertwithTuple(int Number)
        {
            string RomanStr = string.Empty;
            for (int i = 0; Number > 0; i++)
            {
                while (ConvTable.ElementAt(i).Item2 <= Number)
                {
                    RomanStr += ConvTable.ElementAt(i).Item1;
                    Number -= ConvTable.ElementAt(i).Item2;
                }
            }
            return RomanStr;
        }
    }
}

///////Program to test this class
using System;
using System.Collections.Generic;
using System.Linq;

namespace RomanDigits
{
    class Program
    {
        static void Main(string[] args)
        {
            RomanNumeralConverter RC = new RomanNumeralConverter();

            string RomanNumeral = string.Empty;
            int DecimalNumber = 1984;
            RomanNumeral = RC.ConvertwithStruct(DecimalNumber);
            Console.WriteLine("The integer {0} is {1} in roman.", DecimalNumber, RomanNumeral);
            DecimalNumber = 1999;
            RomanNumeral = RC.ConvertwithDict(DecimalNumber);
            Console.WriteLine("The integer {0} is {1} in roman.", DecimalNumber, RomanNumeral);
            DecimalNumber = 42;
            RomanNumeral = RC.ConvertwithTuple(DecimalNumber);
            Console.WriteLine("The integer {0} is {1} in roman.", DecimalNumber, RomanNumeral);

            Console.ReadKey();
        }
    }
}

@Evenbit: Thanks for the reply and the tip on HLA. I'm not that much interested in the conversion, but in the way to do it in C#.

A recursive method using non-subtractive roman numerals:

using System;
using System.Text;

namespace ConsoleApplication1 {
    class Roman {
        String[] digits = { "", "i", "ii", "iii", "iiii", "v", "vi", "vii", "viii", "viiii" };

        public String Convert(int number) {
            String result = String.Empty;
            if (number >= 10) {
                result = MultiplyBy10(Convert(number / 10));
            }
            return result + digits[number % 10];
        }

        private String MultiplyBy10(String roman) {
            StringBuilder sb = new StringBuilder();
            foreach (char c in roman) {
                switch (c) {
                    case 'i': sb.Append('x'); break;
                    case 'v': sb.Append('l'); break;
                    case 'x': sb.Append('c'); break;
                    case 'l': sb.Append('d'); break;
                    case 'c': sb.Append('m'); break;
                    case 'd': sb.Append("mmmmm"); break;
                    case 'm': sb.Append("mmmmmmmmmm"); break;
                    default: break;
                }
            }

            return sb.ToString();
        }
    }
}

@Momerath: Interesting algorithm! But I guess the Romans rather liked to carve MCMXCIX into their stone walls, then mdcccclxxxxviiii, when they had the intention of writing the number 1999

Actually there is no standard and you can find both types of numbers throughout roman history. Wikipedia has an interesting article on this.

@Momerath: Yes I mentioned the same article in my OP. But thanks for your input anyway. I'd better made a thread here so I could call this one solved. I was just curious about what datatype was the best to use. I should have reformulated my title more in the direction of what I was really after, because as everyone knows, roman numerals are too hot of a topic these days;)

Edited 5 Years Ago by ddanbe: n/a

For the sake of the argument you could also implement this with classes, the implementation is similar to that of Type Struct.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RomanNumeralConvertWithClasses
{
    class MainApplication
    {
        
        static void Main(string[] args)
        {
            RomanNumeralConverter[] romArray;
            romArray = new RomanNumeralConverter[]
            {
                new RomanNumeralConverter("M",1000),
                new RomanNumeralConverter("D",500),
                new RomanNumeralConverter("C",100),
                new RomanNumeralConverter("L",50),
                new RomanNumeralConverter("X",10),
                new RomanNumeralConverter("V",5),
                new RomanNumeralConverter("I",1)
            };

            string[] romanNumerals = new string[] { "M", "M", "M", "D", "C", "C", "C", "L", "X", "X", "X", "V", "I", "I", "I" }; // 3888
            int total = 0;
            for (int i = 0; i < romanNumerals.Length; i++)
            {
                for (int j = 0; j < romArray.Length; j++)
                {
                    if (romanNumerals[i] == romArray[j].key)
                    {
                        total += romArray[j].value;
                    }
                }
            }
            Console.WriteLine(total);

        }
    }
    class RomanNumeralConverter
    {
        public string key { get; set; }
        public int value { get; set; }

        public RomanNumeralConverter()
        {

        }
        public RomanNumeralConverter(string key, int value)
        {
            this.key = key;
            this.value = value;
        }
    }
}

because as everyone knows, roman numerals are too hot of a topic these days

Actually, Roman Numerals are quite common in industrial settings. For instance, "25L" would mean 25 stacks of 50 items. You probably run into them quite often on a daily basis without realising it because you are simply not looking for them or simply unaware that that is what the letter means in that particular context.

Actually, Roman Numerals are quite common in industrial settings. For instance, "25L" would mean 25 stacks of 50 items. You probably run into them quite often on a daily basis without realising it because you are simply not looking for them or simply unaware that that is what the letter means in that particular context.

Umm...What industrial settings are you talking about? I work in industrial settings on a regular basis and for the most part things are kept as clear as possible to avoid...umm...people dieing.

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.