可以将扩展方法应用于类吗?
例如,将DateTime扩展为包含可以调用的Tomorrow()方法,如:
DateTime.Tomorrow();
我知道我可以使用
static DateTime Tomorrow(this Datetime value) { //... }
或者
public static MyClass {
public static Tomorrow() { //... }
}
得到类似的结果,但是如何扩展DateTime以便我可以调用DateTime.Tomorrow?
答案 0 :(得分:172)
例如:
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)
我正在寻找类似的东西 - 提供扩展方法的类的约束列表。似乎很难找到一个简明的清单,所以这里是:
您不能拥有任何私人或受保护的内容 - 字段,方法等。
它必须是静态类,如public static class...
。
只有方法可以在类中,并且它们都必须是公共静态的。
您不能使用传统的静态方法 - 不允许使用不包含此参数的方法。
所有方法都必须开始:
public static ReturnType MethodName(此ClassName _this,...)
所以第一个参数总是这个参考。
这会产生一个隐含的问题 - 如果添加需要锁定任何排序的方法,则无法在类级别提供它。通常你会提供一个私有的实例级锁,但是不可能添加任何私有字段,留下一些非常尴尬的选项,比如在一些外部类中将它作为公共静态提供,等等。获取它们。签署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)
}
}