我的问题是,以下是否适当使用C#4中的dynamic
关键字。
我有一些辅助方法,它们提供了比标准ToString
方法更有用的各种对象表示,我用它来进行单元测试。这是一个简化的例子:
public static string PrettyPrint<T>(IEnumerable<T> list)
{
return string.Join(", ", list);
}
// Needed because string is IEnumerable<char>, to prevent
// "Hello" -> "H, e, l, l, o"
public static string PrettyPrint(string s)
{
return s;
}
public static string PrettyPrint(object o)
{
return o.ToString();
}
我用它们是这样的:
public static void PrettyPrinting()
{
object[] things = { 1, "Hello", new int[] {1, 2, 3} };
foreach (dynamic item in things)
{
Console.WriteLine(PrettyPrint(item));
}
}
这会产生以下输出:
1
Hello
1, 2, 3
请注意,如果我将dynamic
关键字替换为object
,我会得到以下内容(所有调用都通过PrettyPrint(object)
路由),这正是我要避免的:< / p>
1
Hello
System.Int32[]
所以我的问题基本上是这是一个代码嗅觉或以这种方式将object
投射到dynamic
是否合法?
答案 0 :(得分:6)
只要你不滥用它,duck typing就像dynamic
被添加到语言中一样。
答案 1 :(得分:3)
不是确切问题的答案,但我会说你的代码不是很OO,这是另一种气味。
理想情况下,您要调用item.PrettyPrint()
,并且每个项目都应返回其表示形式,并覆盖PrettyPrint
。
幸运的是,现有的类型可以使用extension methods进行扩展。它们使您能够添加方法,这就是我要做的事情。
如果你仍然想要在一个类中显示每种类型的逻辑,我会将扩展方法与visitor pattern结合起来。
那就是说,我没有C#环境所以我无法测试我的建议。如果您尝试这个,请告诉我,如果它有效。
答案 2 :(得分:3)
关于你的问题,我不是百分百肯定,因为我不知道你的团队编码风格。 (我也看到一些评论;))
DuckTyping有它的用途 - 但开发人员在使用之前需要知道他们正在做什么。否则就像用剪刀跑;它可能像C#系统中的其他关键字一样被滥用。
就个人而言,我宁愿看到扩展方法,但依赖于开发人员,他/她的论点和完成的文档,我可能会允许它。
我犹豫的最大原因(这个例子对我在网上看过的一些非常温顺)是它阻止你在编译时发现问题。它需要更多的QA测试,更多的边界测试,并且具有更高的失败风险。