2012-08-13 57 views
2

我有一个基类,它有一个抽象方法返回它自己的列表。不匹配的列表类型

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    public abstract class baseclass 
    { 
     public abstract List<baseclass> somemethod();   
    } 
} 

并试图通过返回的* *自我名单覆盖基类的方法的后裔。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class childclass : baseclass 
    { 
     public override List<childclass> somemethod() 
     { 
      List<childclass> result = new List<childclass>(); 
      result.Add(new childclass("test")); 
      return result; 
     } 

     public childclass(string desc) 
     { 
      Description = desc; 
     } 

     public string Description; 
    } 
} 

但我得到这个错误:

Error 1 'ConsoleApplication1.childclass.somemethod()': 
return type must be 'System.Collections.Generic.List<ConsoleApplication1.baseclass>' 
to match overridden member 'ConsoleApplication1.baseclass.somemethod()' 
C:\Users\josephst\AppData\Local\Temporary Projects\ConsoleApplication1childclass.cs 
0 42 ConsoleApplication1 

什么是有一个基类返回它自己的列表的最佳方法,重写基类的方法,做同样的事情?

回答

2

一般是很好的解决方案,但不使用public abstract List<baseclass> somemethod();它是不好的做法

您应该使用non-virtual interface pattern

public abstract class BaseClass<T> 
{ 
    protected abstract List<T> DoSomeMethod(); 

    public List<T> SomeMethod() 
    { 
     return DoSomeMethod(); 
    } 
} 

public class ChildClass : BaseClass<ChildClass> 
{ 
    protected override List<ChildClass> DoSomeMethod(){ ... } 
} 
+0

正如在其他答案中提到的这个相同的建议,[这可能并不总是做你想做的事,或者认为它确实如此。](http://blogs.msdn.com/b/ericlippert/archive/2011/ 02/03/curiouser-and-curiouser.aspx) – Servy 2012-08-13 19:59:18

+0

只是牢记SOLID,一切都很好 – GSerjo 2012-08-13 20:08:30

+0

你看起来像这个解决方案是非常优越的,当它不是。这实际上很有缺陷。它可以在不引起这些问题的情况下使用,当然,对于几乎所有的设计/模式都是如此。 – Servy 2012-08-13 20:12:36

2

当覆盖一个方法时,覆盖方法的签名必须是,确切地说与被覆盖的方法的签名相匹配。你可以用泛型来实现你想要的功能:

public abstract class BaseClass<T> 
{ 
    public abstract List<T> SomeMethod(); 
} 

public class ChildClass : BaseClass<ChildClass> 
{ 
    public override List<ChildClass> SomeMethod() { ... } 
} 
+0

[请注意,这可能并不总是做你想要它做的事情,或者认为它确实。](http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx) – Servy 2012-08-13 19:30:22

+0

不会'公共抽象列表 SomeMethod()where T:BaseClass;'help? – 2012-08-13 19:30:46

+0

@Servy - 感谢您的有用链接。 – 2012-08-13 19:42:46

1

错误信息是不言自明的。要覆盖您需要返回List<baseclass>的方法。

public override List<baseclass> somemethod() 
{ 
    List<childclass> result = new List<childclass>(); 
    result.Add(new childclass("test")); 
    return result; 
} 
+0

解决了这个问题,但我希望返回的列表具有特定于我的子类的值。 – JosephStyons 2012-08-13 19:30:48

+0

@JosephStyons:你可以返回一个'List ',如上所示。但是如果你想重写方法,方法签名必须返回'List '。你可以将'baseclass'强制转换为'childclass'。 – 2012-08-13 19:33:15