Reputation: 556
I'm posting this question here instead of Software Engineering SE because it sounded like a question which would invite more technical answers. I am asking this simply because I am constantly worried, as I code, that I am doing it the right way (in other words, that my coding techniques are healthy).
Simply put here are the strategies I've concocted up when it comes to achieving a correlation between certain values in methods of my code (see examples for understanding what I mean):
1) Using a dictionary:
class Example
{
private static Dictionary<Type, string> _types = new Dictionary<Type, string>()
{
{ typeof(string), "string" },
{ typeof(Int32), "Int32" },
{ typeof(float), "float" }
};
public static string RetrieveTypeString(Type type)
{
return _types[type];
}
}
Here I would generally employ a dictionary which is accessible to an entire class (I don't enjoy the idea of declaring a dictionary with values known beforehand inside the scope of a method which will be called many times). I like this approach for being very concise and performance-friendly.
2) Create a class to map out the types and loop through instances:
public class TypeInfo
{
public TypeInfo(Type type, string name)
{
Type = type;
Name = name;
}
public Type Type { get; set; }
public string Name { get; set; }
}
class Example
{
List<TypeInfo> _lst = new List<TypeInfo>();
public void SomeMethod()
{
_lst.Add(new TypeInfo(typeof(string), "string"));
_lst.Add(new TypeInfo(typeof(Int32), "Int32"));
_lst.Add(new TypeInfo(typeof(float), "float"));
}
public string RetrieveTypeString(Type type)
{
foreach (TypeInfo t in _lst)
{
if (t.Type == type)
{
return t.Name;
}
}
throw new Exception();
}
}
}
I like to use this whenever I am dealing with a one to many relationship, something with many characteristics. It has the downside that I need to actually create the instances at runtime and store them somewhere upon application load to later retrieve them.
3) Using a method with a switch statement:
class Example
{
public string RetrieveTypeString(Type type)
{
switch (Type.GetTypeCode(type))
{
case TypeCode.String:
return "string";
case TypeCode.Int32:
return "Int32";
case TypeCode.Double:
return "double";
default:
throw new Exception();
}
}
}
Depending on the number of items it can get really big, so I usually avoid doing that, but it is useful for small sets.
4) Other methods, such as the use of alternative collections instead of dictionaries.
Suggestions would be greatly appreciated!
Thanks!
EDIT: As I notice this question can be answered differently depending on context, here is a situation where I wonder which is the best approach: I wrote some code where, when a TextBox or another control is flagged with a validation error, an error message and other graphical elements are displayed according to certain settings which are control specific, which means I had to relate controls to their settings. I solved this by creating a class reuniting all the things I wanted to associate to controls (settings that I had defined) and creating a class level dictionary variable to associate my class to controls. I also created a second class level dictionary to relate one of such settings to yet another class which groups up error messages (I wanted more than one error message for each class instance). Is this approach acceptable, or not recommended?
Upvotes: 1
Views: 120
Reputation: 44200
All of them look pretty reasonable to me.
I wouldn't use a list for option 2 - you don't care about the order or about duplicates so a set is likely a better choice. I don't know anything about C# but I'd imagine the lookup is faster too.
I always prioritise readability so I'd probably initially opt for a switch statement. This is, in my opinion, the best way to format it:
switch (Type.GetTypeCode(type))
{
case TypeCode.String: return "string";
case TypeCode.Int32: return "Int32";
case TypeCode.Double: return "double";
default:
throw new Exception();
}
If this turned out to be a performance bottleneck, I'd switch it up for a set or a map.
Upvotes: 1