如何使用c#扩展方法扩展类?

时间:2009-07-27 13:44:32

标签: c# extension-methods

可以将扩展方法应用于类吗?

例如,将DateTime扩展为包含可以调用的Tomorrow()方法,如:

DateTime.Tomorrow();

我知道我可以使用

static DateTime Tomorrow(this Datetime value) { //... }

或者

public static MyClass {
  public static Tomorrow() { //... }
}

得到类似的结果,但是如何扩展DateTime以便我可以调用DateTime.Tomorrow?

9 个答案:

答案 0 :(得分:172)

使用extension method

例如:

namespace ExtensionMethods
{
    public static class MyExtensionMethods
    {
        public static DateTime Tomorrow(this DateTime date)
        {
            return date.AddDays(1);
        }    
    }
}

用法:

DateTime.Now.Tomorrow();

AnyObjectOfTypeDateTime.Tomorrow();

答案 1 :(得分:68)

除非将现有类型标记为部分,否则无法将方法添加到现有类型,只能通过扩展方法将显示的方法添加为现有类型的成员。由于这种情况,您无法向类型本身添加静态方法,因为扩展方法使用该类型的实例。

没有什么可以阻止你创建自己的静态助手方法,如下所示:

static class DateTimeHelper
{
    public static DateTime Tomorrow
    {
        get { return DateTime.Now.AddDays(1); }
    }
}

您可以这样使用:

DateTime tomorrow = DateTimeHelper.Tomorrow;

答案 2 :(得分:17)

扩展方法是用于制作静态方法的语法糖,其第一个参数是类型T的实例,看起来好像它们是T上的实例方法。

因此,在制作“静态扩展方法”时,很大程度上会失去这些好处,因为它们会使代码的读者比扩展方法更加困惑(因为它们似乎是完全限定的,但实际上并未在那个类没有语法上的好处(例如能够在Linq中以流畅的方式链接调用)。

由于您无论如何都必须将扩展带入范围,我认为创建它更简单,更安全:

public static class DateTimeUtils
{
    public static DateTime Tomorrow { get { ... } }
}

然后通过以下代码在代码中使用它:

WriteLine("{0}", DateTimeUtils.Tomorrow)

答案 3 :(得分:9)

我能得到答案的最接近的方法是在System.Type对象中添加扩展方法。不漂亮,但仍然很有趣。

public static class Foo
{
    public static void Bar()
    {
        var now = DateTime.Now;
        var tomorrow = typeof(DateTime).Tomorrow();
    }

    public static DateTime Tomorrow(this System.Type type)
    {
        if (type == typeof(DateTime)) {
            return DateTime.Now.AddDays(1);
        } else {
            throw new InvalidOperationException();
        }
    }
}

否则,IMO Andrew和ShuggyCoUk有更好的实施。

答案 4 :(得分:3)

我会像Kumu一样做

namespace ExtensionMethods
{
    public static class MyExtensionMethods
    {
        public static DateTime Tomorrow(this DateTime date)
        {
           return date.AddDays(1);
        }    
    }
}

但称之为新的DateTime()。明天();

认为它比DateTime.Now.Tomorrow();

更多

答案 5 :(得分:3)

它们提供了通过添加新方法来扩展现有类型的功能,而无需对类型进行任何修改。使用实例方法语法从应用程序中的扩展类型的对象调用方法称为“扩展”方法。扩展方法不是类型上的实例成员。 要记住的关键点是,只有在通过using指令将命名空间显式导入应用程序源代码时,扩展方法(定义为静态方法)才在范围内。尽管扩展方法被定义为静态方法,但仍然使用实例语法调用它们。

点击此处查看完整示例 http://www.dotnetreaders.com/articles/Extension_methods_in_C-sharp.net,Methods_in_C_-sharp/201

示例:

class Extension
    {
        static void Main(string[] args)
        {
            string s = "sudhakar";
            Console.WriteLine(s.GetWordCount());
            Console.ReadLine();
        }

    }
    public static class MyMathExtension
    {

        public static int GetWordCount(this System.String mystring)
        {
            return mystring.Length;
        }
    }

答案 6 :(得分:3)

我正在寻找类似的东西 - 提供扩展方法的类的约束列表。似乎很难找到一个简明的清单,所以这里是:

  1. 您不能拥有任何私人或受保护的内容 - 字段,方法等。

  2. 它必须是静态类,如public static class...

  3. 只有方法可以在类中,并且它们都必须是公共静态的。

  4. 您不能使用传统的静态方法 - 不允许使用不包含此参数的方法。

  5. 所有方法都必须开始:

    public static ReturnType MethodName(此ClassName _this,...)

  6. 所以第一个参数总是这个参考。

    这会产生一个隐含的问题 - 如果添加需要锁定任何排序的方法,则无法在类级别提供它。通常你会提供一个私有的实例级锁,但是不可能添加任何私有字段,留下一些非常尴尬的选项,比如在一些外部类中将它作为公共静态提供,等等。获取它们。签署the C# language had kind of a bad turn in the design for these

    解决方法是使用Extension Method类作为常规类的Facade,Extension类中的所有静态方法都可以调用真实类,可能使用a Singleton

答案 7 :(得分:2)

不幸的是,你不能这样做。不过,我相信它会很有用。输入更自然:

DateTime.Tomorrow

比:

DateTimeUtil.Tomorrow

使用Util类,您必须检查两个不同类中是否存在静态方法,而不是一个。

答案 8 :(得分:0)

我们已经通过详细说明改进了答案。现在对扩展方法的理解更加容易

Extension method:这是一种机制,通过它我们可以扩展现有类的行为,而无需使用子类或修改或重新编译原始类或结构。

我们可以扩展我们的自定义类,.net框架类等。

扩展方法实际上是一种在静态类中定义的特殊静态方法。

由于上面已经考虑了DateTime类,因此我们没有将此类用于解释。

以下是示例

//这是一个现有的Calculator类,它只有一个方法(Add)

public class Calculator 
{
    public double Add(double num1, double num2)
    {
        return num1 + num2;
    }

}

// Below is the extension class which have one extension method.  
public static class Extension
{
    // It is extension method and it's first parameter is a calculator class.It's behavior is going to extend. 
    public static double Division(this Calculator cal, double num1,double num2){
       return num1 / num2;
    }   
}

// We have tested the extension method below.        
class Program
{
    static void Main(string[] args)
    {
        Calculator cal = new Calculator();
        double add=cal.Add(10, 10);
        // It is a extension method in Calculator class.
        double add=cal.Division(100, 10)

    }
}