2010-12-02 59 views
2

昨天我通过一些article约EventAggregator走了,还有一些拍摄这样写的代码,object - 最顶级的基类如何得到Method。 [扩展方法]

(Message.Text as object).PublishEvent(PublishEventNames.MessageTextChanged); 

public static class ExtensionServices 
    { 
     //Supplying event broking mechanizm to each object in the application. 
     public static void PublishEvent<TEventsubject>(this TEventsubject eventArgs, string eventTopic) 
     { 
      ServicesFactory.EventService.GetEvent<GenericEvent<TEventsubject>>() 
       .Publish(new EventParameters<TEventsubject> { Topic = eventTopic, Value = eventArgs }); 
     } 
    } 

我的问题是,对象是如何得到的方法“PublishEvent”。我的OOP理解是错误的?

+0

这是C#语言功能吗?还有什么语言支持这个? – Mohanavel 2010-12-02 18:46:29

回答

5

它被实现为在object类的Extension Method

例如,该扩展方法(从链接的文章):

public static class MyExtensions 
{ 
    public static int WordCount(this String str) 
    { 
     return str.Split(new char[] { ' ', '.', '?' }, 
         StringSplitOptions.RemoveEmptyEntries).Length; 
    } 
} 

是在String类中定义(通过使用this String语法和一个静态类的静态方法)。

String中定义的项目中现在有一个WordCount方法(只要它也位于正确的名称空间中)。

+0

为Wordcount +1。完美的例子。 – Mohanavel 2010-12-02 18:47:50

0

的的this TEventsubject eventArgs这部分确定这是一个Extension method

只有语法糖,以便能够写

TEventsubject eventArgs; 
eventArgs.PublishEvent("topic"); 

代替

TEventsubject eventArgs; 
ExtensionServices.PublishEvent(eventArgs, "topic"); 
0

PublishEvent是一个扩展方法。

您可以通过该方法,包括在参数列表中的this关键字的定义出来。

http://msdn.microsoft.com/en-us/library/bb383977.aspx

扩展方法是非常有用的语法;但他们应该谨慎使用:

1)他们可以杂乱的智能感知如果有太多的扩展增加了对非特定类型(如对象)。

2)他们应该被用于增强类/接口继承,而不是取代它。国际海事组织,如果一个方法是在完全不相关的类型之间共享的,那么它是扩展方法的一个很好的候选者。但是如果它在相关类型中共享,那么它是基类中方法的更好选择。

2

扩展方法实际上并没有那么你似乎呼吁方法的对象的一部分。扩展方法处于查找范围中,编译器在查找对象本身范围内的方法后查找。

因此,对于像obj.MyExtension()这样的方法调用,编译器将在obj变量类型的成员中查找“MyExtension”。它不会找到任何匹配,因为“MyExtension”没有在对象的类型中定义。然后,编译器查找名称为“MyExtension”的扩展方法,该扩展方法在当前作用域(由于使用子句)中有一个this参数,该参数的类型与obj实例变量的类型相匹配。如果找到匹配项,则编译器会生成代码,以便使用其他方法调用静态方法,并在this参数中传递obj。

我相信扩展方法范围是“最后机会”查找 - 如果编译器在可用的扩展中找不到“MyExtension”,下一步是编译错误失败。

与扩展方法的棘手的事情是他们唯一可当你添加了使用条款适合当前的源文件添加到实现扩展,使这些范围相应集的引用。

智能感知不会帮助您通过为您添加适当的使用条款来解决这些名称。作为一个用户,你习惯于在特定类型的对象上调用特定的方法,并且在思维上将该方法作为该类型的一部分。当你充实一个新的源文件时,通常会像往常一样编写对该方法的调用,并且因为忘记将包含扩展方法定义的命名空间/程序集引用到您的程序中而导致“找不到”编译器错误源文件。

+1

用于提及Intellisense/easy命名空间分辨率的问题。我发现这种行为很烦人(以及我在我的回答中提到的相反问题,即TOO为诸如System.Object之类的非特定类型定义的许多扩展方法)。 – 2010-12-02 18:43:05