C# 动态创建属性
所以我有一个有很多属性的对象,PropertyNameYear1,PropertyNameYear2,PropertyNameYear3…持续了20年。这些属性可能会随着时间的推移而增长,因此将来我可能需要添加PropertyNameYear21等等 我试图获得这些属性,包括它们的名称和值,而不指定每一个,因为理论上我可以有几十个。我可以使用LINQ和对象初始值设定项来完成,但是我必须指定每个属性两次: 假设存在其他与PropertyNameYearX命名不同的属性,我如何使用LINQ和Refelction?将所有这些属性和仅这些属性获取到一个新/另一个对象中并返回该对象 这是我正在寻找的伪代码:C# 动态创建属性,c#,linq,reflection,C#,Linq,Reflection,所以我有一个有很多属性的对象,PropertyNameYear1,PropertyNameYear2,PropertyNameYear3…持续了20年。这些属性可能会随着时间的推移而增长,因此将来我可能需要添加PropertyNameYear21等等 我试图获得这些属性,包括它们的名称和值,而不指定每一个,因为理论上我可以有几十个。我可以使用LINQ和对象初始值设定项来完成,但是我必须指定每个属性两次: 假设存在其他与PropertyNameYearX命名不同的属性,我如何使用LINQ和Refe
public ReturnType GetSomeObjectWithSpecificProperties(int ID){
var list = SomeObjectRepository.Where(f => f.ID == ID);
var props = list.GetType().GetProperties().ToList();
var SomePropObjectList = props.Where(f => f.Name.Contains("PropertyNameYear")).ToList();
var listToReturn = SomePropObjectList.Select(f => new {
f.Name = f.GetValue(list)
}).ToList();
return listToReturn;
}
您可以使用ExpandooObject从源类对象动态添加属性。假设源类是ClassWithMayProperties:
public object GetObject(ClassWithManyPropererties obj)
{
var props = obj.GetType().GetProperties().Where(p => p.Name.Contains("PropertyNameYear")).ToList();
dynamic returnObject = new ExpandoObject() as IDictionary<string, Object>;
foreach (var property in props)
{
returnObject.Add(property.Name, property.GetValue(obj));
}
return returnObject;
}
您可以使用ExpandooObject从源类对象动态添加属性。假设源类是ClassWithMayProperties:
public object GetObject(ClassWithManyPropererties obj)
{
var props = obj.GetType().GetProperties().Where(p => p.Name.Contains("PropertyNameYear")).ToList();
dynamic returnObject = new ExpandoObject() as IDictionary<string, Object>;
foreach (var property in props)
{
returnObject.Add(property.Name, property.GetValue(obj));
}
return returnObject;
}
我想插一句,说你应该重新考虑你的方法 而不是:
public class NotGood
{
public int PropertyNameYear1{ get; set; }
//repeat 20 times...
public int PropertyNameYear21{ get; set; }
}
……考虑:
public class Better
{
public List<int> PropertyNameYears{ get; } = new List<int>();
}
这是一行代码,它的伸缩性会更好。此外,您还消除了所有笨拙的、基于反射的解析
编辑:正如我在评论中提到的,有时候清理代码的正确方法是与作者讨论坏代码,而不是调整代码以适应它们造成的问题,但是如果没有办法,这里有一种方法需要四行代码:
var obj = new
{
SomeNormalProp = "foo",
ThisIsSilly1 = 1,
ThisIsSilly2 = 2,
ThisIsSilly3 = 3,
ThisIsSilly4 = 4
};
dynamic barfObj = new ExpandoObject();
foreach (var prop in obj.GetType().GetProperties())
if (prop.Name.StartsWith("ThisIsSilly"))
//add property dynamically
((IDictionary<string, object>)barfObj).Add(prop.Name, prop.GetValue(obj));
//now barfObj is exactly what you want.
var sampleVal = barfObj.ThisIsSilly1;
var json = JsonConvert.SerializeObject(barfObj);
或者如果你是一个真正的受虐狂,你有反射。发射:
我想插一句,说你应该重新考虑你的方法 而不是:
public class NotGood
{
public int PropertyNameYear1{ get; set; }
//repeat 20 times...
public int PropertyNameYear21{ get; set; }
}
……考虑:
public class Better
{
public List<int> PropertyNameYears{ get; } = new List<int>();
}
这是一行代码,它的伸缩性会更好。此外,您还消除了所有笨拙的、基于反射的解析
编辑:正如我在评论中提到的,有时候清理代码的正确方法是与作者讨论坏代码,而不是调整代码以适应它们造成的问题,但是如果没有办法,这里有一种方法需要四行代码:
var obj = new
{
SomeNormalProp = "foo",
ThisIsSilly1 = 1,
ThisIsSilly2 = 2,
ThisIsSilly3 = 3,
ThisIsSilly4 = 4
};
dynamic barfObj = new ExpandoObject();
foreach (var prop in obj.GetType().GetProperties())
if (prop.Name.StartsWith("ThisIsSilly"))
//add property dynamically
((IDictionary<string, object>)barfObj).Add(prop.Name, prop.GetValue(obj));
//now barfObj is exactly what you want.
var sampleVal = barfObj.ThisIsSilly1;
var json = JsonConvert.SerializeObject(barfObj);
或者如果你是一个真正的受虐狂,你有反射。发射:
当然,这是一种更好的方法。但是假设我对这个物体没有控制权,你认识那个控制这个物体的人吗?你能往后推吗?有时候,正确的编写好代码的方法超越了代码本身,涉及到与其他开发人员之间的一些来回交流,这些开发人员可以从代码审查中获益。我在寻找如何这样做。有什么方法可以实现我所追求的吗?例如,在JS中,它相当简单。在.NET中,使用dynamic、ExpandoObject或Newtonsoft.JSON也相对简单,但我仍然建议尽可能取消设计。不过,请看经过调整的答案,看看它是如何工作的。因此,我对尼廷发表了评论。这将提供一个键/值对象,而不是一个具有属性的对象,当然,这是一种更好的方法。但是假设我对这个物体没有控制权,你认识那个控制这个物体的人吗?你能往后推吗?有时候,正确的编写好代码的方法超越了代码本身,涉及到与其他开发人员之间的一些来回交流,这些开发人员可以从代码审查中获益。我在寻找如何这样做。有什么方法可以实现我所追求的吗?例如,在JS中,它相当简单。在.NET中,使用dynamic、ExpandoObject或Newtonsoft.JSON也相对简单,但我仍然建议尽可能取消设计。不过,请看经过调整的答案,看看它是如何工作的。因此,我对尼廷发表了评论。这将提供一个键/值对象,而不是一个具有属性的对象,这将生成一个KeyValuePair列表,其中该列表中的每个项都是{key:PropertyNameYear1,value:Val}。我正在尝试获取一个{PropertNameYear1:Val}列表,这将生成一个KeyValuePair列表,其中该列表中的每个项都是{Key:PropertyNameYear1,Value:Val}。我正在尝试获取{PropertNameYear1:Val}的列表