【问题标题】:Is it good practice to cast objects to dynamic so the correct overloaded method is called?将对象强制转换为动态以便调用正确的重载方法是一种好习惯吗?
【发布时间】:2011-11-25 17:19:28
【问题描述】:

我的问题是关于以下内容是否适合在 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) 路由),这是我要避免的:

1
Hello
System.Int32[]

所以我的问题本质上是这是代码异味还是以这种方式将object 转换为dynamic 是否合法?

【问题讨论】:

  • +1 类型系统的酷边缘案例!
  • 有什么替代方案? foreach 循环是最昂贵的循环。我很想看看 CL 如何为此创建代码以及它在现实世界环境中的效率。

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


【解决方案1】:

只要你不滥用它,duck typing 就像这就是 dynamic 被添加到语言中的部分原因。

【讨论】:

  • @errorstacks - var 不是只适用于静态类型的变量吗?我很确定你用 var 声明的任何东西都有一个在编译时已知的类型。
  • @errorstacks: var 根本不是 dynamic。两个完全不同的关键字。
  • 如果我可以在蜂巢中添加一些糖果,当您知道类型但懒得输入时使用 var;P 在运行时您不知道时使用动态类型。你可以建立一个工厂,或者围绕它建立一个子类来提供更强大的基础,但现在它是快速开发与过程/结构的争论。
  • @Ryan but are too lazy to type it out ;P - 完全正确,但是当你投射匿名类型时,它也被使用并且是必要的:-)
  • @Adam 哈哈。我了解 var 关键字的必要性,但我也查看了无数 var-happy 初级开发人员编写的代码...
【解决方案2】:

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

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

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

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

也就是说,我没有 C# 环境,所以我无法测试我的建议。如果你尝试这个,让我知道它是否有效。

【讨论】:

  • 嗯...关于访问者+扩展方法,不确定,但我认为这可能会导致扩展内的代码类似于:... else if (item is string) { visitor.Visit((string)item); } else if (item is IEnumerable) { visitor.Visit((IEnumerable)item) }
【解决方案3】:

至于您的问题,我不能 100% 确定,因为我不了解您的团队的编码风格。 (我也看到小 cmets ;))

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

就个人而言,我更希望看到扩展方法,但取决于开发人员、他/她的论点和完成的文档,我可能会允许它。

我犹豫不决的最大原因(这个例子与我在网上看到的一些例子相比相当温和)是它阻止你在编译时发现问题。它需要更多的 QA 测试、更多的边界测试,并且失败的风险更高。

【讨论】:

  • 哇——显然有人喜欢否决那些对动态类型没有正面评价的答案哈哈。仅仅因为它是新的和花哨的并不意味着它的一切都是惊人的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
  • 2019-11-20
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多