除了从 sealed 类 继承之外,还有其他选择吗?

Is there an alternative to inheriting from sealed classes?

我问这个问题的原因是因为我想创建一个 class,它具有 FileInfo class(派生自 FileInfo)的所有功能,并允许我添加我的拥有它的属性。

我认为一个例子会更多地协作。 我想要的:

BindingList<FileInformation> files = new BindingList<FileInformation>();
public void GatherFileInfo(string path)
{
    files.Add(new FileInformation(path));
    listboxFiles.DataContext = files;
}

class FileInformation : FileInfo
{
    public bool selected = false;
}

与我害怕我必须做的事情相比:

BindingList<FileInformation> files = new BindingList<FileInformation>();
public void GatherFileInfo(string path)
{
    files.Add(new FileInformation(path));
    listboxFiles.DataContext = files;
}

class FileInformation : FileInfo
{
    string path = "<whatever>"
    FileInfo fileInfo = new FileInfo(path);
    public bool selected = false;

    public string Name
    {
        get { return fileInfo.Name }
    }
    //Manually inherit everything I need???
}

这样做的好处是,在 WPF 中,您可以简单地绑定到 class FileInformation 的所有属性,包括那些继承的 FileInfo class.

我从来没有研究过这个问题,也不知道我应该从哪里开始寻找,所以一个例子或一个关于如何做到这一点的线索会很有帮助。

.Net 中确实没有办法从密封的 class 继承。您可以编写扩展方法,但这不允许您添加新的属性或字段。您唯一可以做的另一件事是模拟继承,但是制作您自己的 class,其中包含您要继承的 class 类型的字段,然后手动公开每个 属性和 "base" class 的方法,方法是为每个方法编写一个包装器方法。如果 class 很小,那还不错,但是如果 class 很大,那就很痛苦了。

我编写了代码生成器程序来使用反射自动为我执行此操作。然后我获取它的输出并扩展它。但这不是真正的继承。我个人不喜欢密封 classes 的概念,因为它会阻止扩展那些 classes。但我想他们这样做是出于性能原因。

由于 FileInfo 继承自 MarshalByRefObject,您可以创建一个模仿 FileInfo 的自定义代理并处理您自己的实现中的所有调用。但是,您将无法转换它,更重要的是,您无法使用自定义属性扩展此类 class。无论如何,如果其他人想要这个,SharpUtils 有一些工具可以帮助它。

要继承 sealed class 尝试使用 Decorator 设计模式, 基本思想是创建 OldClass 的私有实例,并手动实现 all 它的方法,如:

public class NewClass
{
    private OldClass oldClass = new OldClass();

    public override string ToString() 
    {
        return oldClass.ToString();
    }
    //void example
    public void Method1()
    {
        oldClass.Method1();
    }
    //primitive type example
    public int Method2()
    {
        return oldClass.Method2();
    } 
    //chaining example, please note you must return "this" and (do not return the oldClass instance).
    public NewClass Method3()
    {
        oldClass.Method3();
        return this;
    }
}

public class Demo
{
    static void Main(string[] args)
    {
       var newClass = new NewClass();
       newClass.Method3();
       WriteLine(newClass);
    }
}