gpt4 book ai didi

c# - 通过动态属性将两个通用列表相交

转载 作者:行者123 更新时间:2023-11-30 12:26:56 24 4
gpt4 key购买 nike

我有两个通用列表,其中有一些要比较的属性,但我希望键标识符是动态的 List<string> .

假设我们有这个类:

class A
{
string Name { get; set; }
string Color1 { get; set; }
string Color2 { get; set; }
string Length { get; set; }
}

用户现在可以从用户界面中选择这些对象的两个列表的哪些属性需要重叠,以便选择正确的对。这存储在 List<string> 中.例如,如果列表字符串包含“Name”和“Color1”,则只会返回“Name”和“Color1”重叠的对象。

我试图编写一个函数,但遗憾的是我不确定应该将通用列表转换到哪个集合以及如何在这些集合上应用属性名称?如果“标识符”的名称始终相同,那么 Linq/Lambda 就不是问题 ;)

提前致谢

最佳答案

你需要为此使用反射。这有效:

public class A
{
public string Name { get; set; }
public string Color1 { get; set; }
public string Color2 { get; set; }
public string Length { get; set; }

public static IEnumerable<A> Intersecting(IEnumerable<A> input, List<string> propertyNames)
{
if(input == null)
throw new ArgumentNullException("input must not be null ", "input");
if (!input.Any() || propertyNames.Count <= 1)
return input;

var properties = typeof(A).GetProperties();
var validNames = properties.Select(p => p.Name);
if (propertyNames.Except(validNames, StringComparer.InvariantCultureIgnoreCase).Any())
throw new ArgumentException("All properties must be one of these: " + string.Join(",", validNames), "propertyNames");

var props = from prop in properties
join name in validNames.Intersect(propertyNames, StringComparer.InvariantCultureIgnoreCase)
on prop.Name equals name
select prop;
var allIntersecting = input
.Select(a => new {
Object = a,
FirstVal = props.First().GetValue(a, null),
Rest = props.Skip(1).Select(p => p.GetValue(a, null)),
})
.Select(x => new {
x.Object, x.FirstVal, x.Rest,
UniqueValues = new HashSet<object>{ x.FirstVal }
})
.Where(x => x.Rest.All(v => !x.UniqueValues.Add(v)))
.Select(x => x.Object);
return allIntersecting;
}
}

示例数据:

var aList = new List<A> { 
new A { Color1 = "Red", Length = "2", Name = "Red" }, new A { Color1 = "Blue", Length = "2", Name = "Blue" },
new A { Color1 = "Red", Length = "2", Name = "A3" }, new A { Color1 = "Blue", Length = "2", Name = "A3" },
new A { Color1 = "Red", Length = "3", Name = "Red" }, new A { Color1 = "Blue", Length = "2", Name = "A6" },
};
var intersecting = A.Intersecting(aList, new List<string> { "Color1", "Name" }).ToList();

关于c# - 通过动态属性将两个通用列表相交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27228706/

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