在属性上实现IEnumerable

Coo*_*kie 3 c# ienumerable

假设上课

public class Foo 
{
    public List<Bar> Bar = new List<Bar>();
    public string Something;
    public TStatus Status;
}
Run Code Online (Sandbox Code Playgroud)

Bar是一个定义为的类

public class Bar
{
    public string Code;
    public string Message;
    public TStatus Status;
}
Run Code Online (Sandbox Code Playgroud)

我需要迭代列表栏,但我不能使用foreach因为我需要实现IEnumerable我是一个新手,我很难解决如何实现它,任何帮助赞赏.

Ada*_*son 11

有几件事:

1.)至于你的实际问题,你有两个选择:

您可以在代码中迭代Bar字段(或属性,如果您将其更改为如下所述的属性):

Foo foo = new Foo();

foreach(Bar bar in foo.Bar)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

或者你可以制作Foo工具IEnumerable<Bar>(这更复杂):

public class Foo : IEnumerable<Bar>
{
    .. your existing code goes here

    public IEnumerator<Bar> GetEnumerator()
    {
        return Bar.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return Bar.GetEnumerator();
    }
}
Run Code Online (Sandbox Code Playgroud)

这将允许您这样做:

Foo foo = new Foo();

foreach(Bar bar in foo)
{

}
Run Code Online (Sandbox Code Playgroud)

就个人而言,我会推荐第一个选项.这是简单的,除非Foo真的(而不是它只是)的集合Bar对象,那么它看起来更直观.

2.)你上面所拥有的不是属性,而是公共领域.一个属性有一个getter和一个setter,看起来像这样:

public class Foo
{
    public string Something
    {
        get { return ...; }
        set { ... = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

属性通常在单个变量上运行,称为后备存储.对于上面的属性,这样的事情:

public class Foo
{
    private string something;

    public string Something
    {
        get 
        { 
            return something; 
        }
        set  
        { 
            something = value; 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

严格地说,你可以放置任何在块中返回字符串的代码get块,你可以在块中放置任何东西set(包括什么,虽然这不是一个好主意).

属性允许您定义行为类似于字段的内容(因为您可以使用等号分配它),但使用您在检索或设置其值时指定的行为.但是,具有非常简单属性的问题之一(只是直接获取/设置后备变量而没有任何其他逻辑)是它实际上做的有点冗长.这就是为什么C#3.0引入了自动属性的概念,如下所示:

public class Foo
{
    public string Something { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在这里,Something 看起来有点像一个领域,但它实际上是一个属性.C#编译器识别该语法(替换码块两者getset只用分号)和为您创建一个背衬和可变插入代码从中读取和写入.