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

发布于 2024-12-17 22:46:49 字数 1058 浏览 0 评论 0原文

我的问题是,接下来的内容是否适合在 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

请注意,如果我用 object 替换 dynamic 关键字,我会得到以下内容(全部调用通过 PrettyPrint(object) 进行路由,这正是我试图避免的:

1
Hello
System.Int32[]

所以我的问题本质上是这是代码味道还是强制转换是合法的一个对象动态 方式?

My question is about whether what follows is an appropriate use of the dynamic keyword in C# 4.

I have some helper methods that provide a more useful representation of various objects than their standard ToString methods do, which I use for unit testing. Here is a simplified example:

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();
}

I use them something like this:

public static void PrettyPrinting()
{
    object[] things = { 1, "Hello", new int[] {1, 2, 3} };

    foreach (dynamic item in things)
    {
        Console.WriteLine(PrettyPrint(item));
    }
}

This produces the following output:

1
Hello
1, 2, 3

Notice that if I replace the dynamic keyword with object, I get the following (all the calls are routed through PrettyPrint(object)), which is what I am trying to avoid:

1
Hello
System.Int32[]

So my question is essentially is this a code smell or is it legitimate to cast an object to dynamic in this way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清醇 2024-12-24 22:46:49

只要你不滥用它,像这样的鸭子打字就是动态 已添加到语言中。

So long as you don't abuse it, duck typing like this is part of the reason dynamic was added to the language.

妄想挽回 2024-12-24 22:46:49

至于你的问题,我不是 100% 确定,因为我不知道你团队的编码风格。 (我也看到很少的评论;))

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

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

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

As to your question, I'm not 100% sure as I don't know your teams style of coding. (I also see little comments ;) )

DuckTyping has it's uses - however a developer needs to know what they're doing before using it. Otherwise it's like running with scissors; it could be abused like other keywords in the C# system.

Personally, I'd rather see extension methods, but depending on the developer, his/her arguments and the documentation done I'd probably allow it.

The biggest reason for my hesitation (and this example is pretty tame to some of the ones I've seen online) is it stops you from finding issues at compile time. It requires more QA testing, a lot more boundary testing, and has a higher risk of failure.

眼中杀气 2024-12-24 22:46:49

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

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

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

如果您仍然想在一个类中显示每种类型的逻辑,我会将扩展方法与 结合起来访客模式

也就是说,我没有 C# 环境,所以我无法测试我的建议。如果您尝试此操作以及它是否有效,请告诉我。

Not an answer to the exact question, but I would say your code is not very OO, which is another smell.

Ideally you want to call item.PrettyPrint() and each item is supposed to return its representation, and override PrettyPrint.

Luckily, existing types can be extended with extension methods. They enable you to add the methods and that's what I would do instead.

If you still want to have the logic for the display of each type in one class, I would combine extension methods with the visitor pattern.

That said, I don't have C# environment so I can't test what I propose. Let me know if you try this, and if it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文