[英]C# - how to loop through each property & value of an object
我在 C# 中有以下DTO
C#
public class Customer
{
public int Id { get; set;}
public string Name { get;set;}
// & so on (say 25 properties)
}
我使用DynmoDb
作为 Db(NoSql),将上述项目添加到 DynamoDb 表中。 这就是我的方法的样子
public async Task<bool> Add(Customer customer)
{
try
{
var res = await _dynamoClient.PutItemAsync(
tableName: _tableName, item: SetObject(customer)).ConfigureAwait(false);
return res.HttpStatusCode == System.Net.HttpStatusCode.OK
}
catch (Exception ex)
{
Logger.Log(ex, eventObj);
return false;
}
}
私有 SetObject() 方法:-
private Dictionary<string, AttributeValue> SetObject(Customer obj)
{
//DynamoDb - Using Low Level API
var attributes = new Dictionary<string,
AttributeValue> {
//Id
{
nameof(obj.Id),
new AttributeValue {
S = obj.Id
}
},
//Name
{
nameof(obj.Name),
new AttributeValue {
S = obj.Name.Trim()
}
},
};
return attributes;
}
这种私有方法对我来说看起来很麻烦且容易出错。 我不想以这种方式逐个查找每个属性。
我在想是否有某种方法可以遍历所有属性并将name
和value
分配给Dictionary
集合
var propsList = typeof(EventTO).GetProperties().Select(x => x.Name).ToList<string>();
这给了我所有的属性名称,但是我如何从传递的 object 类型的客户中获取值和键。
谢谢!
您可以使用反射,像这样,也可以使用 Generics 以获得更好的类型安全性
using System;
using System.Reflection;
class TestClass
{
public int publicIntField;
public string publicStringField;
public int publicIntProp {get; set;}
public string publicStringProp {get; set;}
public static int staticInt;
}
public class Program
{
public static void Main()
{
var src = new TestClass();
src.publicIntField = 7;
src.publicIntProp = 12;
src.publicStringField = "foo";
src.publicStringProp = "baz";
var dest = new TestClass();
DoIt(src, dest);
TestClass dest1 = DoItWithGenerics(src);
}
public static void DoIt(object src, object dest)
{
Console.WriteLine("DoIt");
Type t = src.GetType();
// TODO check the 2 objects have same type
foreach (PropertyInfo p in t.GetProperties(BindingFlags.Public|BindingFlags.Instance))
{
Console.WriteLine(p.Name);
p.SetValue(dest, p.GetValue(src));
}
foreach (FieldInfo fi in t.GetFields(BindingFlags.Public|BindingFlags.Instance))
{
Console.WriteLine(fi.Name);
fi.SetValue(dest, fi.GetValue(src));
}
Console.WriteLine("*****");
}
public static T DoItWithGenerics<T>(T src) where T:new() // only works for types with a default ctor
{
Console.WriteLine("DoItWithGenerics");
Type t = typeof(T);
T dest = new T();
foreach (PropertyInfo p in t.GetProperties(BindingFlags.Public|BindingFlags.Instance))
{
Console.WriteLine(p.Name);
p.SetValue(dest, p.GetValue(src));
}
foreach (FieldInfo fi in t.GetFields(BindingFlags.Public|BindingFlags.Instance))
{
Console.WriteLine(fi.Name);
fi.SetValue(dest, fi.GetValue(src));
}
Console.WriteLine("*****");
return dest;
}
}
在这个小提琴中看到
这是一种克隆每种类型的 object 的方法
它需要一些修改来处理您正在使用的“Trim()”部分。
你最好使用像https://github.com/ServiceStack/PocoDynamo这样的库
这完成了所有映射工作,为您转换为所需的发电机请求,因此您不必担心。
对于 Javascript,AWS 有 documentClient 库,可以让任务更轻松。 对于 .net,我们使用上述库。
//Configuration for client
var awsDb = new AmazonDynamoDBClient("keyId","key",
new AmazonDynamoDBConfig { ServiceURL="http://localhost:8000"});
var db = new PocoDynamo(awsDb);
//Create c# dto
var itemToSave = new Item();
itemToSave.Id = 1;
itemToSave.Name = "Test";
//Single line to save it
db.PutItem(itemToSave);
看看这个: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection 。 它可能会帮助您简化项目、减少冗余并提高性能,并返回变量的值。 我自己还没有使用它,但我的同事是它的忠实粉丝。
我不确定它会在多大程度上帮助你,我不能让我的同事检查这个,因为他正在度假
使用更多反射!
因此,您拥有类型上每个属性的所有名称。 现在您需要一个该类型的实例来获取属性的值。 您可以这样做:
// Assume that 'event' is an instance of EventTO
foreach (var propertyName in propsList)
{
object value = event.GetType().GetProperty(propertyName).GetValue(event, null);
// Do whatever with 'value'
}
如您所见,我们有一些冗余代码(GetType 和 GetProperty),因此我们可以将 PropertyInfo 存储在 a 中并像这样使用它,而不是将我们的属性作为其名称的字符串存储在列表中:
var propsList = typeof(EventTO).GetProperties();
foreach (var property in propsList)
{
object value = property.GetValue(event, null);
}
提示: PropertyInfo有一个名为PropertyType
的属性,它返回属性的类型
我会使用 FastMember 之类的库来遍历 object 中的属性并将其转换为AttributeValue
字典(请参阅: https://github.com/mgravell/fast-member )
与像 FastMember 这样的优化库相比,反射通常非常慢。
public class Dto
{
public string Name { get; set; }
public string Address { get; set; }
}
static void Convert()
{
var dto = new Dto { Name = "Name", Address = "Address" };
var ta = TypeAccessor.Create(typeof(Dto));
var oa = ObjectAccessor.Create(dto);
var values = new Dictionary<string, AttributeValue>();
foreach (var m in ta.GetMembers())
{
values.Add(m.Name, new AttributeValue { S = oa[m.Name].ToString() });
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.