将对象强制转换为动态是一种好习惯,以便调用正确的重载方法吗?

时间:2011-11-25 17:19:28

标签: c# c#-4.0 dynamic coding-style

我的问题是,以下是否适当使用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是否合法?

3 个答案:

答案 0 :(得分:6)

只要你不滥用它,duck typing就像dynamic被添加到语言中一样。

答案 1 :(得分:3)

不是确切问题的答案,但我会说你的代码不是很OO,这是另一种气味。

理想情况下,您要调用item.PrettyPrint(),并且每个项目都应返回其表示形式,并覆盖PrettyPrint

幸运的是,现有的类型可以使用extension methods进行扩展。它们使您能够添加方法,这就是我要做的事情。

如果你仍然想要在一个类中显示每种类型的逻辑,我会将扩展方法与visitor pattern结合起来。

那就是说,我没有C#环境所以我无法测试我的建议。如果您尝试这个,请告诉我,如果它有效。

答案 2 :(得分:3)

关于你的问题,我不是百分百肯定,因为我不知道你的团队编码风格。 (我也看到一些评论;))

DuckTyping有它的用途 - 但开发人员在使用之前需要知道他们正在做什么。否则就像用剪刀跑;它可能像C#系统中的其他关键字一样被滥用。

就个人而言,我宁愿看到扩展方法,但依赖于开发人员,他/她的论点和完成的文档,我可能会允许它。

我犹豫的最大原因(这个例子对我在网上看过的一些非常温顺)是它阻止你在编译时发现问题。它需要更多的QA测试,更多的边界测试,并且具有更高的失败风险。