简体   繁体   English

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

[英]What's the best way to add custom functionality to existing code in C#?

Say, for example, I have many web applications using the same class library compiled into a dll in C# and I want to update a specific method of a class for a particular application. 比方说,我有很多Web应用程序使用在C#中编译成dll的相同类库,我想更新特定应用程序的类的特定方法。 I don't want to change the existing code because it will affect everyone, and I don't want to inherit from a class to create a new one. 我不想更改现有代码,因为它会影响每个人,我不想从类继承来创建新代码。 I just want to change an existing method of a class for an individual application. 我只想更改单个应用程序的类的现有方法。

One way to achieve this would be to have the compiled classes as 'base' classes and have a separate file containing all the override classes inheriting the base classes. 实现此目的的一种方法是将编译的类作为“基础”类,并具有包含继承基类的所有重写类的单独文件。 Then the applications will use the inherited classes. 然后应用程序将使用继承的类。 Then to change a class for an individual application you could just update the inherited classes. 然后,要更改单个应用程序的类,您只需更新继承的类。 The only problem I see with this method is that every application would need 2 files, one of base classes and one of inherited (probably not compiled). 我用这种方法看到的唯一问题是每个应用程序都需要2个文件,一个基类和一个继承(可能没有编译)。

Can anyone recommend a better way of doing this? 任何人都可以推荐更好的方法吗?

也许扩展方法可行?

You can't change the implementation of a compiled method; 您无法更改已编译方法的实现; polymorphism is one option; 多态性是一种选择; the other is encapsulation, perhaps via a decorator pattern over an interface, using a factory to create the instance - ie 另一种是封装,可能是通过接口上的装饰器模式,使用工厂来创建实例 - 即

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" }
}

(I won't bother with an example of polymorphism) (我不会打扰多态的例子)

Polymorphism and decoration achieve a similar end, but have different pros/cons - for example, decorators can be assembled in flexible chains for different scenarios. 多态性和装饰实现了类似的目的,但具有不同的优点/缺点 - 例如,装饰器可以在灵活的链中组装以用于不同的场景。

With any other approach (such as extension methods), you end up calling a different method; 使用任何其他方法(例如扩展方法),您最终会调用另一种方法; if that suits, then fine. 如果那适合,那很好。

If you simply want to add stuffs in the methods, and not modify its contents, you can use Aspect Oriented Programming (AOP). 如果您只是想在方法中添加内容而不修改其内容,则可以使用面向方面编程 (AOP)。 In C#, this can be done using PostSharp or AspectDNG . 在C#中,可以使用PostSharpAspectDNG来完成。

AOP focuses on the separation of concerns: you write methods containing only business logic, and every other aspects of the application (security, logging, and so on) are encapsulated in their own modules. AOP侧重于关注点的分离:您编写的方法只包含业务逻辑,应用程序的其他各个方面(安全性,日志记录等)都封装在自己的模块中。 At compile time, these aspects' code are injected into the business code in particular locations you specified. 在编译时,这些方面的代码将被注入到您指定的特定位置的业务代码中。

You can also have a look at this question . 你也可以看看这个问题 Even though the question aims specifically at runtime modification of methods, some answers might give you some hints. 即使问题专门针对方法的运行时修改,一些答案可能会给你一些提示。

I think extension methods is the best option. 我认为扩展方法是最好的选择。 For more information go here . 有关更多信息,请转到此处

It seems strange that you can't override an existing method without using an inherited class. 在不使用继承类的情况下,您无法覆盖现有方法,这似乎很奇怪。 This is very straightforward in languages like javascript. 这在javascript等语言中非常简单。 The above suggestions have given me food for thought but nether really improve on my initial idea. 以上建议给了我深思,但是我的初步想法确实改善了。 Extension methods don't allow you to modify the existing method. 扩展方法不允许您修改现有方法。 With encapsulation I would still need to use a new class. 使用封装,我仍然需要使用新类。

Say I had 10 applications all using the class User with method login(). 假设我有10个应用程序都使用类user和方法login()。 I don't want to change where this method is called (ie. changing classname or method parameters). 我不想改变调用此方法的位置(即更改类名或方法参数)。 I just want to change the method itself for that application so additional checks can be made before returning. 我只想更改该应用程序的方法本身,以便在返回之前进行额外的检查。

Is it possible to make the method in the class library Virtual? 是否可以在类库Virtual中创建该方法? This would allow you to override it where you want to but keep it "as is" otherwise. 这将允许您在您想要的地方覆盖它,但另外保持“原样”。

Polymorphism seems to be the best solution for this. 多态性似乎是最好的解决方案。 This way base classes can be compiled and left alone and inherited classes can be changed for individual applications without changing the way the original is used (unless necessary). 这样就可以编译基类并保持单独使用,并且可以为各个应用程序更改继承类,而无需更改原始使用方式(除非必要)。

BaseClasses.cs BaseClasses.cs

public class BaseUser {

    public BaseUser() {}

    public bool login() {

        return false;

    }

}

Classes.cs Classes.cs

public class User : BaseUser {}

Application 应用

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

Extension methods. 扩展方法。 This should be added to a static class. 这应该添加到静态类。 You should visit: http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx 您应该访问: http//weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx

Example of an extension method for the DateTime class to make it return the week number: 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;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将i18n添加到现有的自定义CMS系统(使用C#构建)的最佳方法是什么? - What is the best way to add i18n to an existing custom CMS system (build with C#)? 将项目添加到C#数组的最佳方法是什么? - What's the best way to add an item to a C# array? 在C#中模拟Python的“ in”关键字功能的最佳方法? - Best way to emulate the functionality of Python's “in” keyword in C#? 在 linux 上用 c 代码调用 c# 代码的最佳方法是什么 - What's the best way to call c# code in c code on linux 将列添加到现有数据集中的最佳方法是什么? - What's the best way to add a column to an existing dataset? 从C#执行添加/更新数据库操作的最佳方法是什么? - What's the best way to do an Add/Update DB operation from C#? 在C#中从非异步调用异步代码的最佳方法是什么(Fire和Forget) - what's the best way to invoke Async Code from Non Async in C# (Fire and Forget) C# .NET 组织 SQL 查询并拥有干净代码的最佳方法是什么 - C# .NET What's the best way to organize SQL queries and have clean code 在Custom TimePicker中的C#中声明时间变量的最佳方法是什么 - What is the best way to declare a time variable in C# in Custom TimePicker 考虑到 C# 或 Java 中的这种设计,哪种方式最好同时遵守 DRY 和限制意外功能? - What way would be best to adhere to both DRY and limit unintended functionality given this kind of design in C# or Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM