C#-如何在不显式调用属性名的情况下为对象指定属性值

C#-如何在不显式调用属性名的情况下为对象指定属性值,c#,.net,dictionary,C#,.net,Dictionary,我有一个应用程序,其中我有一个具有100个属性值的类 比如说 Class RequestData{ String PropertName1 {get;set;} String PropertName2 {get;set;} String PropertName3 {get;set;} . . . String PropertName100 {get;set;} } 我有一个列表>,它有所有的propertyname和PropertyValue。所以,理想情况下这是 Propert

我有一个应用程序,其中我有一个具有100个属性值的类

比如说

Class RequestData{
 String PropertName1 {get;set;}
 String PropertName2 {get;set;}
 String PropertName3 {get;set;}
 .
 .
 .
 String PropertName100 {get;set;}
}
我有一个列表>,它有所有的propertyname和PropertyValue。所以,理想情况下这是

PropertName1 = "Timothy"
PropertName2 = "rajan"
.
.
.
PropertName100 = "alex"
我需要创建RequestData的实例,并将所有属性值分配给每个属性名

在这个场景中,我需要这样做,这将导致100行

 RequestData requestData = new RequestData ();
 requestData.PropertName1 = "Timothy" ;
 requestData.PropertName2 = "Rajan" ;
 requestData.PropertName3 = "Alex" ;
有更好的方法吗?我可以循环到列表中,但不知道如何巧妙地执行类似的操作

 RequestData requestData = new RequestData ();
 requestData.[key]= value ;

我希望我说清楚了。任何帮助都会很好。

您可以通过反射来实现这一点

_list = new List<Tuple<string, string>>
   {
      new Tuple<string, string>("PropertName1", "asd"),
      new Tuple<string, string>("PropertName2", "sdfgds"),
      new Tuple<string, string>("PropertName3", "dfgdfg"),
      new Tuple<string, string>("PropertName100", "dfgdfg")
   };


var requestData = new RequestData();

foreach (var tuple in _list)
{
   requestData.GetType()
              .GetProperty(tuple.Item1, BindingFlags.Public| BindingFlags.NonPublic | BindingFlags.Instance )
             ?.SetValue(requestData, tuple.Item2);

}
\u list=新列表
{
新元组(“PropertName1”、“asd”),
新元组(“PropertName2”、“sdfgds”),
新元组(“PropertName3”、“dfgdfg”),
新元组(“PropertName100”、“dfgdfg”)
};
var requestData=new requestData();
foreach(变量元组在_列表中)
{
requestData.GetType()
.GetProperty(tuple.Item1,BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
?SetValue(requestData,tuple.Item2);
}
或者一种扩展方法

public void UpdateProperties<T>(this T obj, List<Tuple<string, string>> list) where T : class
{
   foreach (var tuple in _list)
   {
      var type = obj.GetType();
         var property = type.GetProperty(tuple.Item1, BindingFlags.Public| BindingFlags.NonPublic | BindingFlags.Instance );
      if(property == null)
         continue;
      property.SetValue(obj, tuple.Item2);
   }
}
public void UpdateProperties(这个T对象,列表),其中T:class
{
foreach(变量元组在_列表中)
{
var type=obj.GetType();
var property=type.GetProperty(tuple.Item1,BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if(属性==null)
继续;
SetValue(obj,tuple.Item2);
}
}

其他资源

搜索具有指定名称的公共属性

设置指定对象的特性值

指定控制绑定的标志以及搜索的方式 对于成员和类型,是通过反射进行的


是的,你能做到。没有更多的细节,但很难给出“好”的回应。根据您所展示的内容(我可能做出了一个不好的假设),这里有几种可能的方法之一。我个人并不推荐这样做,但也许它(连同其他答案/评论)会让你走上你真正想要/需要走的道路

我应该提到有更有效的方法来实现这一点,但我想展示一个基本的方法,它可能更明显地反映出实际发生的情况

    static void Main()
    {
        var propertyList = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("PropertyName1","Value1"),
            new KeyValuePair<string, string>("PropertyName2","Value2"),
            new KeyValuePair<string, string>("PropertyName3","Value3"),
            new KeyValuePair<string, string>("PropertyName4","Value4"),
            new KeyValuePair<string, string>("PropertyName5","Value5"),
        };

        var requestData = new RequestData();
        //reflection allows you to loop through the properties of a class
        foreach (var property in requestData.GetType().GetProperties())
        {
            //you can loop through your list (here I made an assumption that it's a list of KeyValuePair)
            foreach (var keyValuePair in propertyList)
            {
                //if the key matches the property name, assign the value
                if (property.Name.Equals(keyValuePair.Key))
                {
                    property.SetValue(requestData, keyValuePair.Value);
                }
            }
        }

        //to show that they are properly set
        Console.WriteLine(requestData.PropertyName1);
        Console.WriteLine(requestData.PropertyName2);
        Console.WriteLine(requestData.PropertyName3);
        Console.WriteLine(requestData.PropertyName4);
    }
}

public class RequestData
{
    public string PropertyName1 { get; set; }
    public string PropertyName2 { get; set; }
    public string PropertyName3 { get; set; }
    public string PropertyName4 { get; set; }
}
static void Main()
{
var propertyList=新列表
{
新的KeyValuePair(“PropertyName1”、“Value1”),
新的KeyValuePair(“PropertyName2”、“Value2”),
新的KeyValuePair(“PropertyName3”、“Value3”),
新的KeyValuePair(“PropertyName4”、“Value4”),
新的KeyValuePair(“PropertyName5”、“Value5”),
};
var requestData=new requestData();
//反射允许您循环遍历类的属性
foreach(requestData.GetType().GetProperties()中的var属性)
{
//您可以循环浏览您的列表(这里我假设它是一个KeyValuePair列表)
foreach(propertyList中的var keyValuePair)
{
//如果键与属性名匹配,请指定值
if(property.Name.Equals(keyValuePair.Key))
{
SetValue(requestData,keyValuePair.Value);
}
}
}
//以显示它们已正确设置
Console.WriteLine(requestData.PropertyName1);
Console.WriteLine(requestData.PropertyName2);
Console.WriteLine(requestData.PropertyName3);
Console.WriteLine(requestData.PropertyName4);
}
}
公共类请求数据
{
公共字符串PropertyName1{get;set;}
公共字符串PropertyName2{get;set;}
公共字符串PropertyName3{get;set;}
公共字符串PropertyName4{get;set;}
}

将另一个类似的答案放入环中,这个答案使用字符串列表并在
=
符号上拆分它们,然后使用反射尝试获取属性名称,如果该名称不为空,则设置对象的属性值:

private static void Main()
{
    var propNamesAndValues = new List<string>
    {
        "PropertName1 = Timothy",
        "PropertName2 = Rajan",
        "PropertName100 = Alex",
    };

    var requestData = new RequestData();

    foreach (var propNameValue in propNamesAndValues)
    {
        var parts = propNameValue.Split('=');
        if (parts.Length < 2) continue;

        var propName = parts[0].Trim();
        var propValue = parts[1].Trim();

        typeof(RequestData).GetProperty(propName)?.SetValue(requestData, propValue);
    }

    Console.WriteLine("{0} {1} {2}", requestData.PropertName1,
        requestData.PropertName2, requestData.PropertName100);

    GetKeyFromUser("\nDone! Press any key to exit...");
}
private static void Main()
{
var propNamesAndValues=新列表
{
“PropertName1=Timothy”,
“PropertName2=Rajan”,
“PropertName100=Alex”,
};
var requestData=new requestData();
foreach(propNamesAndValues中的变量propNameValue)
{
var parts=propNameValue.Split('=');
如果(零件长度<2)继续;
var propName=parts[0]。Trim();
var propValue=parts[1]。Trim();
typeof(RequestData).GetProperty(propName)?.SetValue(RequestData,propValue);
}
Console.WriteLine(“{0}{1}{2}”),requestData.PropertName1,
requestData.PropertName2,requestData.PropertName100);
GetKeyFromUser(“\n完成!按任意键退出…”);
}
输出


如果您只是创建一个请求对象,为什么不使用
ExpandoObject
-您可以将其视为字典或对象。您没有显示列表,而是显示了类似于多个赋值的内容。请出示“财产名称和价值清单”的实际样本好吗?它是否类似于
var-propnameandvalues=newlist{“PropertName1=Timothy”、“PropertName2=rajan”、…、“PropertName100=alex”}
另一个想法是,如果你能获得JSON格式的输入,那么你可以使用它并将其反序列化到你的
RequestData
对象中。正如@gilliduck所指出的,如果没有更多你想要实现的内容的上下文,这个问题实际上是无法回答的。例如,您正在谈论的“RequestData”是什么?如果属性的名称匹配,也许可以使用AutoMapper或其他库。