C#扩展方法 - 到目前为止有多远?

时间:2008-12-16 13:17:27

标签: c# ruby-on-rails extension-methods

Rails引入了一些Ruby的核心扩展,如3.days.from_now返回,因为您预计将来会有三天的日期。使用C#中的扩展方法,我们现在可以执行类似的操作:

static class Extensions
{
    public static TimeSpan Days(this int i)
    {
        return new TimeSpan(i, 0, 0, 0, 0);
    }

    public static DateTime FromNow(this TimeSpan ts)
    {
        return DateTime.Now.Add(ts);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(
            3.Days().FromNow()
        );
    }
}

或者怎么样:

static class Extensions
{
    public static IEnumerable<int> To(this int from, int to)
    {
        return Enumerable.Range(from, to - from + 1);
    }
}

class Program
{
    static void Main(string[] args)
    {
        foreach (var i in 10.To(20))
        {
            Console.WriteLine(i);
        }
    }
}

这是根本错误的,还是有时候这是一个好主意,比如像Rails这样的框架?

7 个答案:

答案 0 :(得分:8)

我非常喜欢扩展方法,但我觉得当它们在LINQ之外使用时,它们会以可维护性为代价提高可读性。

3.Days().FromNow()为例。这非常具有表现力,任何人都可以阅读此代码并准确地告诉您它的作用。这是一件非常美好的事情。作为编码员,我们喜欢编写自我描述和表达的代码,因此它几乎不需要任何评论,并且很高兴阅读。在这方面,这段代码至关重要。

然而,作为编码员,我们也对后代负责,而那些追随我们的人将花费大部分时间来试图理解这段代码是如何运作的。我们必须小心,不要那么表达,调试我们的代码需要在无数的扩展方法中跳跃。

扩展方法掩盖了“如何”更好地表达“什么”。我想这使得它们成为一把双刃剑,最适合(如同所有事情)适度使用。

答案 1 :(得分:6)

首先,我的直觉:3.Minutes.from_now看起来很酷,但没有证明为什么扩展方法是好的。这也反映了我的一般观点:很酷,但我从来没有真正错过它们。


问题:3.Minutes是时间跨度还是角度?

通过using语句“正常”引用的命名空间仅影响类型,现在他们突然决定3.Minutes的含义。

所以最好的是“不要让他们逃脱” 可能被引用的命名空间中的所有公共扩展方法最终都是“全球化的” - 与此相关的所有潜在问题。将它们保留在程序集内部,或将它们放入单独的命名空间中,该命名空间将单独添加到每个文件中。

答案 2 :(得分:5)

我个人喜欢int.To,我对int.Days感到矛盾,我不喜欢TimeSpan.FromNow。

我不喜欢我所看到的'流畅'界面有点流行,让你编写伪英文代码,但是通过实现名称可能孤立无助的方法来实现。

例如,这对我来说不太好看:

TimeSpan.FromSeconds(4).FromNow()

显然,这是一个主观的事情。

答案 3 :(得分:1)

我同意siz和瘦保守派在这个问题上的看法。 Rails有这样的东西,所以它并不是那么令人困惑。当您编写“days”和“fromnow”方法时,无法保证您的代码没有错误。此外,您正在为代码添加依赖项。如果将扩展方法放在自己的文件中,则需要在每个项目中使用该文件。在项目中,您需要在需要时包含该项目。

所有这一切,对于其他框架/世界中存在的非常简单的扩展方法(如Jeff使用"left"或thatismatt使用days.fromnow),我认为没关系。任何熟悉日期的人都应该理解“3.Days()。FromNow()”的含义。

答案 4 :(得分:0)

至少目前,我处于频谱的保守一方,并且反对扩展方法。对我来说,只是语法糖并不重要。对于初级开发人员来说,如果他们不熟悉C#,我认为这也是一场噩梦。我宁愿将扩展封装在我自己的对象或静态方法中。

如果您打算使用它们,请不要过度使用它们,以免让自己变得方便,但会碰到触及代码的任何其他人。 : - )

答案 5 :(得分:0)

每种语言都有自己的观点,关于语言应该是什么。 Rails和Ruby的设计都有自己独特的意见。 PHP有明显不同的意见,C(++ /#)......和Visual Basic一样(虽然显然我们不喜欢他们的风格)。

天平具有许多易于阅读的内置功能,而不是对所有内容的细节控制。我不希望你每次想要做任何事情时都要去查找很多函数(而且必须有一个膨胀框架的性能开销),但我个人喜欢Rails,因为它节省了我很多时候都在发展。

我想我在这里说的是,如果你正在设计一种语言,采取立场,从那里开始,并建立你(或你的目标开发者会)最常使用的功能

答案 6 :(得分:0)

我个人的偏好是暂时使用它们并等待微软和其他大型组织如何使用它们。如果我们开始看到很多代码,教程和书籍都使用像3.Days()这样的代码。从FromNow()开始,它会使用很多代码。如果只有少数人使用它,那么您就有可能难以维护代码,因为没有足够的人熟悉扩展的工作方式。

在相关的说明中,我想知道正常for循环和foreach循环之间的性能如何比较?看起来第二种方法会涉及计算机的大量额外工作,但我对这个概念不太熟悉,无法确切知道。