我有一个MyClass列表
public class MyClass
{
public string Title { get; set; }
public string Name { get; set; }
}
var records = new List<MyClass>
{
new MyClass { Title = "Mr", Name = "Bob" },
new MyClass { Title = "Dr", Name = "Jon" },
};
我需要在类的每个属性中的每个值以及列表中的每个项目周围添加“”。因此,每个属性的实际内容在开头和结尾处都包含一个“。
有没有一种方法可以添加此属性,而不必遍历每个属性和项目并手动完成。也许是使用Linq的方法?
我在Google上找不到任何东西,我甚至不确定要搜索什么。
谢谢
答案 0 :(得分:3)
是的,只需映射转换即可:
var transformedRecords =
records.Select(c =>
new MyClass
{
Title = $"\"{c.Title}\"",
Name = $"\"{c.Name}\""
});
现在,如果您想要的是一种无需手动手动更改所有string
属性的方法,那么唯一的方法就是反射:
static void Transform<T>(T t)
where T: class
{
if (ReferenceEquals(t, null))
throw new ArgumentNullException(nameof(t));
var propertiesToEdit =
typeof(T).GetProperties(BindingFlags.Public |
BindingFlags.Instance)
.Where(p => p.PropertyType == typeof(string)
p.CanWrite &&
p.CanRead);
foreach (var p in propertiesToEdit)
{
p.SetValue(t, $"\"{p.GetValue(t)}\"");
}
}
但是现在您有了一个方法,可以对传递给它的对象进行突变。永远不要在LINQ上使用变异方法,否则会出现意想不到的行为。
因此,最好只是简单地手动进行迭代:
foreach (var r in records)
Transform(r);
现在您的records
列表将包含突变的项目。
当然,您无需在string
停留,可以用很少的额外费用使这一点变得更加普遍:
static void Transform<T, Q>(T t, Func<Q, Q> transform)
where T: class
{
if (ReferenceEquals(t, null))
throw new ArgumentNullException(nameof(t));
var propertiesToEdit =
typeof(T).GetProperties(BindingFlags.Public |
BindingFlags.Instance)
.Where(p => p.PropertyType == typeof(Q)
p.CanWrite &&
p.CanRead);
foreach (var p in propertiesToEdit)
{
p.SetValue(t, transform((Q)p.GetValue(t)));
}
}
现在您将像这样使用它:
foreach (var r in records)
Transform(r, (string s) => $"\"{s}\"");
class
约束在这里很重要,因为这会因值类型而失败; c#默认使用按值传递语义,因此该方法将变异副本,而不是列表中的原始实例。
答案 1 :(得分:0)
在不使用循环的情况下,我相信这是您想要的:
records.ForEach(e =>
{
e.Name = $"\"{e.Name}\"";
e.Title = $"\"{e.Title}\"";
});