[英]How to delegate interface implementation to other class in C#
假設以下課程:
public class MyEnum: IEnumerator
{
private List<SomeObject> _myList = new List<SomeObject>();
...
}
有必要在MyEnum中實現IEnumerator方法。 但是,是否可以將IEnumerator的實現直接“委托”或重定向到_myList而無需實現IEnumerator方法?
方法1:繼續使用封裝並將調用轉發到List實現。
class SomeObject
{
}
class MyEnum : IEnumerable<SomeObject>
{
private List<SomeObject> _myList = new List<SomeObject>();
public void Add(SomeObject o)
{
_myList.Add(o);
}
public IEnumerator<SomeObject> GetEnumerator()
{
return _myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
class Program
{
static void Main(string[] args)
{
MyEnum a = new MyEnum();
a.Add(new SomeObject());
foreach (SomeObject o in a)
{
Console.WriteLine(o.GetType().ToString());
}
Console.ReadLine();
}
}
方法2:從List實現繼承,您可以免費獲得該行為。
class SomeObject
{
}
class MyEnum : List<SomeObject>
{
}
class Program
{
static void Main(string[] args)
{
MyEnum a = new MyEnum();
a.Add(new SomeObject());
foreach (SomeObject o in a)
{
Console.WriteLine(o.GetType().ToString());
}
Console.ReadLine();
}
}
方法1允許更好的沙盒,因為在沒有MyEnum知識的情況下沒有將在List中調用的方法。 最少努力方法2是優選的。
你可以這樣做:
public class MyEnum : IEnumerator {
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator GetEnumerator() { return this._myList.GetEnumerator(); }
}
原因很簡單。 您的類可以包含多個集合字段,因此編譯器/環境無法知道應該使用哪個字段來實現“IEnumerator”。
EIDT:我同意@pb - 你應該實現IEnumerator <SomeObject>接口。
除了使用pb的方法之外,由於“簡單”的原因,這是不可能的:接口方法需要傳遞一個this
指針作為第一個參數。 當您在對象上調用GetEnumerator
時,此指針將成為您的對象。 但是,為了使調用在嵌套列表上工作,指針必須是對該列表的引用,而不是對您的類的引用。
因此,您必須明確地將該方法委托給另一個對象。
(順便說一句,其他回復中的建議是正確的:使用IEnumerator<T>
, 而不是 IEnumerable
!)
如果要以調用者無法修改集合的方式返回集合,您可能希望將List包裝到ReadOnlyCollection <>中並返回ReadOnlyCollection <>的IEnumerable <>。
這樣您就可以確保不會更改您的收藏。
除非您從List <T>派生。
public class MyEnum : List<SomeObject>, IEnumerable<SomeObject>{}
謝謝大家的意見和解釋。 最后,我將您的一些答案結合到以下內容中:
class MyEnum : IEnumerable<SomeObject>
{
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator<SomeObject> GetEnumerator()
{
// Create a read-only copy of the list.
ReadOnlyCollection<CustomDevice> items = new ReadOnlyCollection<CustomDevice>(_myList);
return items.GetEnumerator();
}
}
此解決方案是確保調用代碼無法修改列表,並且每個枚舉器在各方面都與其他枚舉器無關(例如,使用排序)。 再次感謝。
請注意,由於duck-typing ,你可以在任何具有GetEnumerator
方法的對象上使用foreach
- 對象類型不需要實際實現IEnumerable
。
所以,如果你這樣做:
class SomeObject
{
}
class MyEnum
{
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator<SomeObject> GetEnumerator()
{
return _myList.GetEnumerator();
}
}
然后這很好用:
MyEnum objects = new MyEnum();
// ... add some objects
foreach (SomeObject obj in objects)
{
Console.WriteLine(obj.ToString());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.