【问题标题】:What's the best way to add custom functionality to existing code in C#?在 C# 中向现有代码添加自定义功能的最佳方法是什么?
【发布时间】:2009-01-21 12:20:26
【问题描述】:

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

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

谁能推荐一个更好的方法?

【问题讨论】:

    标签: c# inheritance


    【解决方案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" }
    }
    

    (多态的例子我就不多说了)

    多态和装饰实现了相似的目的,但有不同的优缺点 - 例如,装饰器可以针对不同的场景组装成灵活的链。

    使用任何其他方法(例如扩展方法),您最终都会调用不同的方法;如果合适,那就没问题了。

    【讨论】:

      【解决方案3】:

      如果你只是想在方法中添加东西,而不是修改它的内容,你可以使用Aspect Oriented Programming (AOP)。在 C# 中,这可以使用 PostSharpAspectDNG 来完成。

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

      您也可以查看this question。尽管该问题专门针对方法的运行时修改,但一些答案可能会给您一些提示。

      【讨论】:

        【解决方案4】:

        我认为扩展方法是最好的选择。欲了解更多信息,请转到here

        【讨论】:

          【解决方案5】:

          如果不使用继承类就不能覆盖现有方法,这似乎很奇怪。这在 javascript 等语言中非常简单。上述建议给了我思考的余地,但确实比我最初的想法有所改进。扩展方法不允许您修改现有方法。通过封装,我仍然需要使用一个新类。

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

          【讨论】:

            【解决方案6】:

            是否可以将类库中的方法设为虚拟?这将允许您在您想要的地方覆盖它,但在其他情况下保持“原样”。

            【讨论】:

              【解决方案7】:

              多态性似乎是最好的解决方案。通过这种方式,可以编译基类并将其单独保留,并且可以针对单个应用程序更改继承的类,而无需更改原始类的使用方式(除非必要)。

              BaseClasses.cs

              public class BaseUser {
              
                  public BaseUser() {}
              
                  public bool login() {
              
                      return false;
              
                  }
              
              }
              

              类.cs

              public class User : BaseUser {}
              

              应用

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

              【讨论】:

              • 部分原因是,当您更改库类时,您可以查看是否会破坏任何内容,而无需进入每个应用程序并检查修改。抽象/虚拟的东西越多,对库的更改就越困难。
              【解决方案8】:

              扩展方法。这应该添加到静态类中。您应该访问: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;
                  }
              

              【讨论】:

              • 扩展方法只允许您向类添加新方法,而不是覆盖现有方法。这很有趣,但不是我想要的。
              猜你喜欢
              • 2018-07-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-07-29
              • 2015-12-11
              相关资源
              最近更新 更多