产量的有用性

时间:2016-05-21 00:33:41

标签: c# linq yield

我想知道yield何时有用。在我看来,每次我可以使用public class Test { public object Test1; public object Test2; public Test(object test1, object test2) { this.Test1 = test1; this.Test2 = test2; } } 时都可以使用DataTable

假设我有 Test

DataTable dt1 = new DataTable();
dt1.Columns.Add("test1", typeof(string));
dt1.Columns.Add("test2", typeof(string));
dt1.Rows.Add("a1", "a2");
dt1.Rows.Add("b1", "b2");

DataTable dt2 = new DataTable();
dt2.Columns.Add("test1", typeof(string));
dt2.Columns.Add("test2", typeof(string));
dt2.Rows.Add("c1", "c2");
dt2.Rows.Add("d1", "d2");

这两个IEnumerable<Test> s

IEnumerable<Test> GetTests(DataTable dt)
{
    foreach (DataRow row in dt.Rows)
    {
        yield return new Test(row["test1"], row["test2"]);
    }
}

IEnumerable<Test> tests = GetTests(dt1);

示例1

如果我想为 dt1 获得IEnumerable<Test> testsLinq = dt1.Rows.OfType<DataRow>() .Select(row => new Test(row["test1"], row["test2"])); 我可以

yield

但我可以做到

IEnumerable<Test> MergeTests(DataTable dt1, DataTable dt2)
{
    foreach (DataRow row in dt1.Rows)
    {
        yield return new Test(row["test1"], row["test2"]);
    }

    foreach (DataRow row in dt2.Rows)
    {
        yield return new Test(row["test1"], row["test2"]);
    }
}

IEnumerable<Test> mergedTests = MergeTests(dt1, dt2);

示例2

我知道的另一个IEnumerable<Test> mergedTestsLinq = dt1.Rows.OfType<DataRow>() .Select(row => new Test(row["test1"], row["test2"])) .Union(dt2.Rows.OfType<DataRow>() .Select(row => new Test(row["test1"], row["test2"]))); 用途是合并

yield

但是,我能再做一次

Linq

是否存在某些情况我不知道var coords = []; var address = '1600 Pennsylvania Ave NW, Washington, DC 20500'; var geocoder = new google.maps.Geocoder(); geocoder.geocode({'address': address}, function( results, status ) { if (status === google.maps.GeocoderStatus.OK) { coords[0] = results[0].geometry.location.lat(); coords[1] = results[0].geometry.location.lng(); } else { coords = 'Could not retrieve coordinates for: ' + address; } }); return coords; 最适合{{1}}使用哪些?

1 个答案:

答案 0 :(得分:1)

当数据结构不是线性时,

yield return会更加灵活。

例如,您可以使用它按预订,后序或按顺序枚举树:

IEnumerable<T> InorderTree<T>(TreeNode<T> node) {
    if (node.Left != null) {
        foreach (var x in InorderTree(node.Left)) {
            yield return x;
        }
    }
    if (node.Right != null) {
        foreach (var x in InorderTree(node.Right)) {
            yield return x;
        }
    }
    yield return node.Value;
}

您还可以生成一个产生Fibonacci数字序列的方法:

IEnumerable<int> Fibonacci(int n) {
    int first = 0, second = 1;
    for (int c = 0 ; c < n ; c++ ) {
        int next;
        if ( c <= 1 ) {
            next = c;
        } else {
            next = first + second;
            first = second;
            second = next;
        }
        yield return next;
    }
}