我在描述到的問題在標題一時間難以超越的接口特性,對不起,如果標題不清晰的。如何具有遺傳型
假設我有以下接口/類:現在
public interface IAction { /*...*/ }
public class WriteAction : IAction { /*...*/ }
public class ReadAction : IAction { /*...*/ }
,這些操作將在其他類中使用。 ReadWriteTest
可以同時擁有ReadAction
和WriteAction
對象,但ReadTest
只能有ReadAction
對象。
請注意,這些測試對象做的不僅僅是這些,我正在編輯其他功能,因爲它們與問題無關。
兩個xxxTest
類共享一個通用的接口。所以接口和ReadWriteTest
類的實現如下:
public interface ITest
{
List<IAction> Actions { get; set; }
}
public class ReadWriteTest : ITest
{
public List<IAction> Actions { get; set; }
}
的問題是,對於ReadTest
類,我想只包含ReadAction
元素,以限制該屬性。
我試圖執行如下:
public class ReadTest : ITest
{
public List<ReadAction> Actions { get; set; }
}
在我看來,這應該工作,因爲每個ReadAction
固有實現IAction
接口。
但是,編譯器不喜歡它,並告訴我ReadTest
類沒有實現所有需要的IAction
屬性。
有沒有辦法來限制此的ActionList在ReadTest
類定義的內容?
我可以通過創建一個自定義的AddAction(IAction action)
方法來解決這個問題,該方法根本不會添加任何WriteAction
對象,但我希望得到更加優雅的解決方案來解決這個問題。
這可能嗎?對最終結果
作爲回答
更新,它可以通過添加一個泛型類型的接口來完成。這解決了我所描述的問題,但遺憾的是並沒有解決更大的問題。添加此generict類型意味着我現在無法將任何Test對象作爲ITest
,因爲我現在需要指定通用參數,這對於任一Test都是不同的。
該解決方案(或至少,我的解決方案)是從ITest
接口刪除Actions
財產。 Actions
屬性仍然存在於類中。
我在界面中添加了一個Run()
方法,而不是在界面中定義列表屬性。此方法將遍歷任一Test類中本地定義的Actions
列表。
所以,作爲一個快速概述:
foreach(ITest myTest in myTests)
{
myTest.Run()
}
類實施ReadWriteTest
:
public List<IAction> Actions {get; set;}
public void Run()
{
foreach(IAction action in Actions) { /*...*/ }
}
類實施ReadTest
:
public List<ReadAction> Actions {get; set;}
public void Run()
{
foreach(IAction action in Actions) //I could also declare it as a ReadAction. Either works.
{ /*...*/ }
}
如果我正確理解你的(超級!)答案,在泛型類型T上使用'out'關鍵字允許T自動轉換爲它的任何繼承類型或實現的接口?另外,如果我不向接口屬性添加'set',我是否仍然可以實際添加一個'set'到實現接口的實際類?如果我例如在我的接口屬性(例如'string Name {get;}')上只有'get',我仍然可以在實際的類上實現一個'set'(例如'public string Name {get; set;}'),或者這在使用'out'關鍵字的情況下是不可能的? – Flater 2014-09-26 11:49:30
忽略我的第二個問題,我忘了'readonly' :) – Flater 2014-09-26 11:53:37
@Flater答案是「kindof」。這實際上相當複雜,並且與您只使用類型T作爲輸出的事實有關。我無法在這裏解釋這一切,但[這裏是關於它的微軟文章](http://msdn.microsoft.com/en-us/library/dd799517.aspx)。 – 2014-09-26 12:00:38