2012-08-13 54 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