gpt4 book ai didi

c# - LINQ 到对象 : Is there a way to pass to LINQ the accessor from which to get values?

转载 作者:行者123 更新时间:2023-11-30 19:30:10 25 4
gpt4 key购买 nike

我似乎找不到让 LINQ 从指定访问器返回值的方法。我知道每个对象的访问器名称,但不确定是否可以将请求的访问器作为变量传递或以其他方式实现所需的重构。

考虑以下代码片段:

// "value" is some object with accessors like: format, channels, language
row = new List<String> {
String.Join(innerSeparator, (from item in myObject.Audio
orderby item.Key ascending
select item.Value.format).ToArray()),
String.Join(innerSeparator, (from item in myObject.Audio
orderby item.Key ascending
select item.Value.channels).ToArray()),
String.Join(innerSeparator, (from item in myObject.Audio
orderby item.Key ascending
select item.Value.language).ToArray()),
// ...
}

我想将其重构为一个使用指定访问器的方法,或者可能传递一个委托(delegate),但我不知道它是如何工作的。

string niceRefactor(myObj myObject, string /* or whatever type */ ____ACCESSOR) {
return String.Join(innerSeparator, (from item in myObject.Audio
orderby item.Key ascending
select item.Value.____ACCESSOR).ToArray());
}

我已经编写了大量的 C#,但对 LINQ 的魔力还是陌生的。这是正确的方法吗?您将如何重构它?

最佳答案

我先提取最明显的共性:

var audioItems = myObject.Audio.OrderBy(item => item.Key);
row = new List<String> {
String.Join(innerSeparator, audioItems.Select(x => x.Value).ToArray());
String.Join(innerSeparator, audioItems.Select(x => x.Format).ToArray());
String.Join(innerSeparator, audioItems.Select(x => x.Channels).ToArray());
String.Join(innerSeparator, audioItems.Select(x => x.Language).ToArray());
}

如果我使用的是 .NET 4,那么我将删除 ToArray 调用,因为 string.Join 现在有更多重载:

var audioItems = myObject.Audio.OrderBy(item => item.Key);
row = new List<String> {
String.Join(innerSeparator, audioItems.Select(x => x.Value));
String.Join(innerSeparator, audioItems.Select(x => x.Format));
String.Join(innerSeparator, audioItems.Select(x => x.Channels));
String.Join(innerSeparator, audioItems.Select(x => x.Language));
}

可能到此为止。但是如果你愿意,你总是可以添加另一种扩展方法:

public static string Separate<T>(this IEnumerable<T> items, string separator)
{
return string.Join(separator, items);
}

然后:

var audioItems = myObject.Audio.OrderBy(item => item.Key);
row = new List<String> {
audioItems.Select(x => x.Value).Separate(innerSeparator));
audioItems.Select(x => x.Format).Separate(innerSeparator));
audioItems.Select(x => x.Channels).Separate(innerSeparator));
audioItems.Select(x => x.Language).Separate(innerSeparator);
}

我几乎肯定会到此为止。您可以继续:

public static IEnumerable<string> ProjectAndSeparateMany<T>(
this IEnumerable<T> items, string separator, Func<T, object>... projections)
{
return projections.Select(projection => items.Select(projection)
.Separate(separator);
}

并调用它:

var audioItems = myObject.Audio.OrderBy(item => item.Key);
row = audioItems.ProjectAndSeparateMany(innerSeparator,
x => x.Value, x => x.Format, x => x.Channels, x => x.Language).ToList();

...但在这一点上它是如此专家,我怀疑我是否会再次使用它...

关于c# - LINQ 到对象 : Is there a way to pass to LINQ the accessor from which to get values?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9843668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com