0

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

就像您有一个创建表格的类,但是您需要允许用户重新定义创建表格单元格的方法,以让用户在此单元格中打印自定义内容。但是,该类具有打印单元格内容的默认方式(以防用户不需要自定义它)。

是否有任何常用或标准化的方法来实现这一目标?

4

3 回答 3

7

更新

有“花生画廊”指出我的方法(在底部)不符合要求,这是另一种方法:

使用委托。使用 Action 或 Func 类型定义某些公共属性。在代码中需要调用这些行为的地方,将属性与 null 进行比较。如果为 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 类型派生,但可以为它们编写扩展方法。

于 2016-11-10T21:37:44.630 回答
1

假设您能够修改现有类,您应该将您的方法标记为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
    }
}

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

于 2016-11-10T21:48:40.947 回答
-1

我终于结束了这个解决方案。它是由@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 委托进行了扩展。这样,我可以允许我的软件模块的用户只扩展一种方法,而不会弄乱其他类和对象。

于 2016-11-10T23:10:59.667 回答