我有List<object>
。我想循环遍历列表并以比o.ToString()
更友好的方式打印出值,以防某些对象是布尔值或日期时间等。
如何构建一个我可以调用MyToString(o)
的函数并返回一个正确格式化的字符串(由我指定)作为其实际类型?
答案 0 :(得分:6)
您可以在.NET 4.0中使用dynamic keyword,因为您正在处理内置类型。否则,您将使用多态性。
示例:
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
答案 1 :(得分:1)
取决于设计的重要性:
if (TryGetValue(o.GetType, out show)) show.Show(o);
答案 2 :(得分:1)
您是否考虑以更友好的方式覆盖ToString()?
答案 3 :(得分:1)
这是一个带注释的工作示例。它使用通用的Type of Dictionary和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());
}
}
}
答案 4 :(得分:0)
您唯一的选择是if-else-if结构。 switch不允许打开类型,因为switch结构需要一个具有互斥值的可枚举集合(并且一个对象可以有几种类型)。
编辑阿巴斯评论:
GetType()。名称有效但会导致您在此上下文中出现潜在错误,因为它可能会返回您不知道的类型。即使一个对象存储为类型A,GetType()。如果B继承A,Name也可能返回“B”。如果你在执行切换的方法的上下文中不知道B(它可能是一个类型来自另一个继承了当前库之一的库,它可能是在你编写方法后添加的类型),你会在伪类型切换中错过它。如果你写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(":(");
}
}
交换机的概念与非互斥值不兼容。这就是为什么当值不是独占的时,当你打开Flags枚举时,你可以得到编译错误。
答案 5 :(得分:0)
这样的事可能会让你在路上:
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;
}
希望这有帮助! ;)