一种在c#中扩展现有类而不创建新类的方法

本文关键字:创建 方法 新类 扩展 一种 | 更新日期: 2023-09-27 18:17:25

我有一个很好的完整的类,这是做可怕的事情。我需要允许用户通过替换其中的一些方法来使用这个类,但是不允许继承,因为这个类也在其他应用程序类中使用。

这就像你有一个创建表格的类,但是你需要允许用户重新定义创建表格单元格的方法,让用户在这个单元格中打印一些自定义的东西。然而,这个类有一个默认的方式来打印单元格内容(以防用户不需要自定义它)。

是否有通用的或标准化的方法来实现这一点?

一种在c#中扩展现有类而不创建新类的方法

已更新

吃了"花生画廊";指出我的方法(在底部)不符合要求,这里有另一种方法:

使用代表团。定义某些类型为Action或Func的公共属性。在代码中需要调用这些行为的地方,将属性与null进行比较。如果为空,则使用默认行为。如果没有,调用这些值。

你的调用代码可以设置属性,但不是必须的。

(第一次尝试)替代方法:

您正在描述一个扩展方法,或者如果可用的话,可以使用继承。

扩展方法使您能够"添加";方法转换为现有类型,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊类型的静态方法,但是调用它们时就好像它们是扩展类型上的实例方法一样。对于用c#和Visual Basic编写的客户端代码,调用扩展方法和在类型中实际定义的方法之间没有明显的区别。

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

继承、封装和多态性是面向对象编程的三个主要特征(或支柱)之一。继承使您能够创建重用、扩展和修改在其他类中定义的行为的新类。继承其成员的类称为基类,继承这些成员的类称为派生类。派生类只能有一个直接基类。然而,继承是可传递的。如果ClassC从ClassB派生,而ClassB从ClassA派生,则ClassC继承在ClassB和ClassA中声明的成员。
https://msdn.microsoft.com/en-us/library/ms173149.aspx

你不能从所有的。net类型中派生,但是你可以为它们编写扩展方法。

假设您能够修改现有的类,您应该将您的方法标记为virtual

这将允许您提供默认实现(这是您现有代码将使用的),并能够在需要的地方使用自定义实现来覆盖它。

你的基类可以是这样的:

public class TableMaker
{
    public virtual string MakeTable()
    {
        //Provide default implementation used by existing code here
    }
}

你的继承类可以重写虚方法:

public class SpecialTableMaker : TableMaker
{
    public override string MakeTable()
    {
        //Provide specific implementation for cell text here
    }
}

您现有的代码将正常工作,您可以在需要的地方使用其他类

我终于结束了这个解决方案。它是由@codenoir提出的,但是我也有一个演示整个机制的代码。

public class MyTable
{
    public delegate string OnInsertHandler();
    public event OnInsertHandler OnInsert;

    public string Show()
    {
        string res = "-BEGIN-";
        if (OnInsert != null) {
            res += OnInsert ();
        } else {
            res += "#default insert#";
        }
        res += "-END-";
        return res;
    }
}

public class DelegateTester
{
    public void OnTest()
    {
        MyTable mt = new MyTable();
        Debug.Log("Default output: " + mt.Show());  // Shows "-BEGIN-#default insert#-END-"
        // Changing functionality via delegate
        mt.OnInsert += MyCustomInsert;
        Debug.Log("Customized output: " + mt.Show());   // Shows "-BEGIN-#custom insert#-END-"
        // Remove delegate
        mt.OnInsert -= MyCustomInsert;
        Debug.Log("Rollbacked output: " + mt.Show());   // Shows "-BEGIN-#default insert#-END-"
    }
    public string MyCustomInsert()
    {
        return "#custom insert#";
    }
}

在这个例子中,我使用MyTable类,它是使用Func委托扩展的。这样,我可以允许我的软件模块的用户只扩展一个方法,而不会与其他类和对象混淆。