2015-04-22 29 views
1

我之所以问这个问题,是因为我想创建一个具有FileInfo类的所有功能的类(从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中你可以简单的绑定类FileInformation的所有属性,包括那些继承的FileInfo类。

我从来没有看过这个问题,我没有导致我应该开始寻找的地方,所以如何做到这一点的示例或领导将是有益的。

+2

为什么”你是通过公共属性公开一个嵌套在FileInformation类中的'FileInfo'对象,而不是一个接一个地为它的属性声明包装? –

+0

这将是一种可能性,但为了代码可读性,我想知道如果不通过对象绑定到像'FileI.FullName'这样的属性,这是否可能。这也不总是最佳做法。 – DerpyNerd

+1

为了代码可读性,您不应该继承类。如果有什么东西在你尝试使用它的时候是有害的。此外,“选定”是您在UI上执行的操作,它可能不应该存在于模型中。 – Kcvin

回答

2

真的没有办法从.NET中的密封类继承。您可以编写扩展方法,但这不允许您添加新的属性或字段。唯一可以做的其他事情是模拟继承,但是让自己的类包含要从其继承的类的类型的字段,然后通过编写包装来手动公开“基本”类的每个属性和方法方法为每一个。如果班级很小,这并不坏,但如果班级很大,就会变得很痛苦。

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

+0

这就是我害怕的......太糟糕了 – DerpyNerd

+0

我放弃寻找懒惰的解决方案。你是绝对正确的。 – DerpyNerd

0

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

1

从密封类继承尝试使用装饰设计模式, 的基本思想是创造OldClass的私有实例,并手动执行所有它的方法,如:

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); 
    } 
}