在C#中为现有代码添加自定义功能的最佳方法是什么?

时间:2009-01-21 12:20:27

标签: c# inheritance

比如说,我有很多Web应用程序使用在C#中编译成dll的相同类库,我想更新特定应用程序的类的特定方法。我不想更改现有代码,因为它会影响每个人,我不想从类继承来创建新代码。我只想为单个应用程序更改类的现有方法。

实现此目的的一种方法是将编译的类作为“基础”类,并具有包含继承基类的所有重写类的单独文件。然后应用程序将使用继承的类。然后,要更改单个应用程序的类,您只需更新继承的类。我用这种方法看到的唯一问题是每个应用程序都需要2个文件,一个基类和一个继承(可能没有编译)。

有人可以推荐一种更好的方法吗?

8 个答案:

答案 0 :(得分:5)

也许扩展方法可行?

答案 1 :(得分:2)

您无法更改已编译方法的实现;多态性是一种选择;另一种是封装,可能是通过接口上的装饰器模式,使用工厂来创建实例 - 即。

interface IFoo { void Bar();}
class Foo : IFoo {public void Bar() { /* imp 1 */ } }
class FooWrapper : IFoo {
    IFoo parent;
    public FooWrapper(IFoo parent) {this. parent = parent;}
    public void Bar() { /* imp 2, perhaps using "parent" }
}

(我不会打扰多态性的例子)

多态性和装饰实现了类似的目的,但具有不同的优点/缺点 - 例如,装饰器可以灵活地组装在不同的场景中。

使用任何其他方法(例如扩展方法),您最终会调用另一种方法;如果那样,那就好了。

答案 2 :(得分:2)

如果您只想在方法中添加内容,而不是修改其内容,则可以使用Aspect Oriented Programming(AOP)。在C#中,可以使用PostSharpAspectDNG完成此操作。

AOP专注于关注点的分离:您编写的方法只包含业务逻辑,而应用程序的其他所有方面(安全性,日志记录等)都封装在自己的模块中。在编译时,这些方面的代码将被注入到您指定的特定位置的业务代码中。

您还可以查看this question。即使问题专门针对方法的运行时修改,一些答案可能会给你一些提示。

答案 3 :(得分:0)

我认为扩展方法是最好的选择。有关更多信息,请访问here

答案 4 :(得分:0)

如果不使用继承的类,则无法覆盖现有方法,这似乎很奇怪。这在javascript等语言中非常简单。以上建议给了我深思,但是我的初步想法确实改善了。扩展方法不允许您修改现有方法。使用封装,我仍然需要使用新类。

假设我有10个应用程序都使用类user和方法login()。我不想改变调用此方法的位置(即更改类名或方法参数)。我只想更改该应用程序的方法本身,以便在返回之前进行额外的检查。

答案 5 :(得分:0)

是否可以在类库Virtual中创建该方法?这将允许您在您想要的地方覆盖它,但保持“原样”。

答案 6 :(得分:0)

多态性似乎是最好的解决方案。这样就可以编译基类并保持单独使用,并且可以为各个应用程序更改继承类,而无需更改原始文件的使用方式(除非必要)。

BaseClasses.cs

public class BaseUser {

    public BaseUser() {}

    public bool login() {

        return false;

    }

}

Classes.cs

public class User : BaseUser {}

应用

User u = new User();
u.login(); 

答案 7 :(得分:0)

扩展方法。这应该添加到静态类。您应该访问:http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx

DateTime类的扩展方法示例,使其返回周数:

public static int WeekNumber(this DateTime dtPassed)
    {
        CultureInfo ciCurr = CultureInfo.CurrentCulture;
        int weekNum = 0;
        try
        {
            weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed,
           CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday);
        }
        catch (Exception ex)
        {
            //TODO: Add error handling code
        }

        return weekNum;
    }