我有一个 List<object>
。我想循环遍历列表并以比只使用o.ToString()
更友好的方式打印值,以防某些对象是布尔值,日期时间等。
你将如何构造一个函数,让我可以像这样调用MyToString(o)
并返回正确格式化(由我指定)的字符串,以适应其实际类型?
例如:
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");
}
}
打印输出:
I'm a date
I'm a bool
I'm an int
System.Boolean
继承。 - wsanvilleusing 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());
}
}
}
这取决于设计的重要性:
if (TryGetValue(o.GetType, out show)) show.Show(o);
if(obj is A)
,您就不会错过它。/// <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;
}
}
这个注释是错误的,因为
public class Bar : Foo
{
}
public static void CaseTypeSpecialized()
{
Foo obj = new Bar();
CaseType(obj);
}
会显示 ":("。
如果你写成,则可以正常工作
/// <summary>
/// Displays ":)" if obj is a Foo
/// </summary>
public static void CaseType(object obj)
{
if (obj is "Foo")
{
MessageBox.Show(":)");
}
else
{
MessageBox.Show(":(");
}
}
switch的概念与非互斥值不兼容。这就是为什么在对Flags枚举进行switch时,如果值不是互斥的,就会出现编译错误。
类似这样的东西可能会帮助你入门:
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;
}
Dictionary<Type,Func<Object, String>>
。 - George Duckett