比如说,我有很多Web应用程序使用在C#中编译成dll的相同类库,我想更新特定应用程序的类的特定方法。我不想更改现有代码,因为它会影响每个人,我不想从类继承来创建新代码。我只想为单个应用程序更改类的现有方法。
实现此目的的一种方法是将编译的类作为“基础”类,并具有包含继承基类的所有重写类的单独文件。然后应用程序将使用继承的类。然后,要更改单个应用程序的类,您只需更新继承的类。我用这种方法看到的唯一问题是每个应用程序都需要2个文件,一个基类和一个继承(可能没有编译)。
有人可以推荐一种更好的方法吗?
答案 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#中,可以使用PostSharp或AspectDNG完成此操作。
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;
}