I have a List
. I want to loop over the list and print the values out in a more friendly manner than just o.ToString()
in case some of
that depends on how important the design will be:
if (TryGetValue(o.GetType, out show)) show.Show(o);
Somthing like this might get you on the way:
private static String MyToString(object o)
{
var val = "";
switch (o.GetType().Name)
{
case "Boolean": val = ((bool)o) ? "this is true" : "this is false"; break;
case "DateTime": val = "The date is: " + ((DateTime)o); break;
case "Int32": val = "The number-value is: " + (int)o; break;
}
return val;
}
Hope this helps! ;)
Your only option is an equivalent to if-else-if structure. switch does not allow switch on type, because the switch structure needs an enumerable ensemble with mutually exclusive values (and an object can be of several types).
Edit for Abbas comment:
GetType().Name is valid but will lead you to potential errors in this context, because it can return a type you don't know. Even if an object is stored as a type A, GetType().Name can potentially return "B" if B inherits A. If you don't know B in the context of the method doing the switch (it could be a type from another library that inherits one of the current library, it could be a type that has been added after you wrote your method), you will miss it in your pseudo-typeswitch. If you write if(obj is A)
though, you won't.
Example, if I write this:
/// <summary>
/// Displays ":)" if obj is a Foo
/// </summary>
public static void CaseType(object obj)
{
switch(obj.GetType().Name)
{
case "Foo":
MessageBox.Show(":)");
break;
default:
MessageBox.Show(":(");
break;
}
}
The comment is a lie, because
public class Bar : Foo
{
}
public static void CaseTypeSpecialized()
{
Foo obj = new Bar();
CaseType(obj);
}
will display ":(".
It will work if you write
/// <summary>
/// Displays ":)" if obj is a Foo
/// </summary>
public static void CaseType(object obj)
{
if (obj is "Foo")
{
MessageBox.Show(":)");
}
else
{
MessageBox.Show(":(");
}
}
It's the concept of switch that is incompatible with non-mutually exclusive values. That's why you can get compilation errors when you switch on a Flags enum when the values are not exclusives.
Here's a working example with comments. It uses a generic Dictionary of Type and Lambda Func.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
// a custom class
public class MyPerson
{
public string FN { get; set; }
public string LN { get; set; }
}
static void Main(string[] args)
{
// your prebuilt dictionary of Types to Lambda expressions to get a string
Dictionary<Type, Func<object, String>> MyToStringLookup = new Dictionary<Type, Func<object, string>>()
{
{typeof(String), new Func<Object, String>( obj => obj.ToString() )},
{typeof(DateTime), new Func<Object, String>( obj => ((DateTime)obj).ToString("d") )},
{typeof(MyPerson), new Func<Object, String>( obj => (obj as MyPerson).LN )},
};
// your list of objects
List<Object> MyObjects = new List<Object>()
{
"abc123",
DateTime.Now,
new MyPerson(){ FN = "Bob", LN = "Smith"}
};
// how you traverse the list of objects and run the custom ToString
foreach (var obj in MyObjects)
if (MyToStringLookup.ContainsKey(obj.GetType()))
System.Console.WriteLine(MyToStringLookup[obj.GetType()](obj));
else // default if the object doesnt exist in your dictionary
System.Console.WriteLine(obj.ToString());
}
}
}
You can use the dynamic keyword for this with .NET 4.0, since you're dealing with built in types. Otherwise, you'd use polymorphism for this.
Example:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
List<object> stuff = new List<object> { DateTime.Now, true, 666 };
foreach (object o in stuff)
{
dynamic d = o;
Print(d);
}
}
private static void Print(DateTime d)
{
Console.WriteLine("I'm a date"); //replace with your actual implementation
}
private static void Print(bool b)
{
Console.WriteLine("I'm a bool");
}
private static void Print(int i)
{
Console.WriteLine("I'm an int");
}
}
Prints out:
I'm a date
I'm a bool
I'm an int
Did you consider overriding ToString() in a more friendly way?