Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有一种将对象属性转换为字典的简单方法<;字符串,字符串>;_C#_Asp.net_Dictionary_Reflection - Fatal编程技术网

C# 是否有一种将对象属性转换为字典的简单方法<;字符串,字符串>;

C# 是否有一种将对象属性转换为字典的简单方法<;字符串,字符串>;,c#,asp.net,dictionary,reflection,C#,Asp.net,Dictionary,Reflection,我有一个数据库对象(一行),它有许多属性(列),映射到表单字段(asp:textbox、asp:dropdownlist等)。我想将这个对象和属性转换成字典映射,使其更易于迭代 例如: Dictionary<string, string> FD = new Dictionary<string,string>(); FD["name"] = data.name; FD["age"] = data.age; FD["occupation"] = data.occupation

我有一个数据库对象(一行),它有许多属性(列),映射到表单字段(asp:textbox、asp:dropdownlist等)。我想将这个对象和属性转换成字典映射,使其更易于迭代

例如:

Dictionary<string, string> FD = new Dictionary<string,string>();
FD["name"] = data.name;
FD["age"] = data.age;
FD["occupation"] = data.occupation;
FD["email"] = data.email;
..........
Dictionary FD=new Dictionary();
FD[“name”]=data.name;
FD[“年龄”]=data.age;
FD[“职业”]=数据。职业;
FD[“email”]=data.email;
..........
如果不手动键入所有不同的100个属性,我如何轻松地执行此操作


注意:FD字典索引与数据库列名相同。

假设
数据
是某个对象,并且希望将其公共属性放入字典,则可以尝试:

原件-出于历史原因(2012年):

Dictionary FD=(从data.GetType().GetProperties()中的x选择x)
.ToDictionary(x=>x.Name,x=>(x.getMethod().Invoke(data,null)==null?”:x.getMethod().Invoke(data,null.ToString());
更新(2017年):

Dictionary Dictionary=data.GetType().GetProperties()
.ToDictionary(x=>x.Name,x=>x.GetValue(数据)?.ToString()???);

HtmlHelper类允许将Anonymous对象转换为RouteValueDictionary,我想您可以在每个值上使用.ToString()来获得字符串重新表述:

 var linkAttributes = System.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes(linkHtmlAttributes);
缺点是这是ASP.NET MVC框架的一部分。使用.NET Reflector,方法内部的代码如下所示:

public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes)
{
   RouteValueDictionary dictionary = new RouteValueDictionary();
  if (htmlAttributes != null)
  {
     foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes))
     {
            dictionary.Add(descriptor.Name.Replace('_', '-'), descriptor.GetValue(htmlAttributes));
       }
 }
    return dictionary;
 }
你会看到这个代码和Yahia给你的答案是一样的,他的答案提供了一个口述。使用我给你们的反射代码,你们可以很容易地将RouteValueDictionary转换成口述,但Yahia的答案是一行

编辑-我添加了一个代码,用于执行转换的方法:

编辑2-我在代码中添加了空检查,并使用了字符串值的String.Format

    public static Dictionary<string, string> ObjectToDictionary(object value)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        if (value != null)
        {
            foreach (System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(value))
            {
                if(descriptor != null && descriptor.Name != null)
                {
                     object propValue = descriptor.GetValue(value);
                     if(propValue != null)
                          dictionary.Add(descriptor.Name,String.Format("{0}",propValue));
            }
        }
        return dictionary;
    }
publicstaticdictionary ObjectToDictionary(对象值)
{
字典=新字典();
if(值!=null)
{
foreach(System.ComponentModel.TypeDescriptor.GetProperties(值)中的System.ComponentModel.PropertyDescriptor描述符)
{
if(描述符!=null&&descriptor.Name!=null)
{
object propValue=descriptor.GetValue(值);
if(propValue!=null)
Add(descriptor.Name,String.Format(“{0}”,propValue));
}
}
返回字典;
}
从一本字典转到一个对象检查,这是在这个线程中建议的

公共静态类MyExtensions
{
公共静态字典ToDictionary(此对象myObj)
{
返回myObj.GetType()
.GetProperties()
.Select(pi=>new{Name=pi.Name,Value=pi.GetValue(myObj,null)})
.工会(
myObj.GetType()
.GetFields()
.Select(fi=>new{Name=fi.Name,Value=fi.GetValue(myObj)})
)
.ToDictionary(ks=>ks.Name,vs=>vs.Value);
}
}

看看
系统.ComponentModel.TypeDescriptor.GetProperties(…)
。这是正常数据绑定位的工作方式。它将使用反射并返回一组属性描述符(您可以使用这些描述符获取值)。您可以通过实现
ICustomTypeDescriptor

来定制这些描述符的性能。这比硬编码等额值快吗?我们可以反转此过程,将FD字典转换回字符串对象吗?我将对此进行一些测试。您的代码有语法错误CS1922:无法初始化类型“System.Collective”ons.Generic.KeyValuePair'具有集合初始值设定项,因为它未实现“System.Collections.IEnumerable”@Dexter corrected-had
{
而不是
。请再试一次。另一个错误是它说ToDictionary不能接受零参数。我认为它需要将KeyValuePair作为参数或其他什么。是的--哇,wtf…你的算法刚从2900万纳秒变为200万纳秒。它可以处理空值!最好的答案是你。我不使用MVC,我正在转换数据对象,而不是处理html。@Dexter您可能没有使用MVC,但我给了您“AnonymousObjectToHtmlAttributes”方法的代码,以了解它的作用。我不确定处理html是什么意思。如果您指的是“HtmlHelper”namespace,仅此而已,是一些方法的命名空间容器。我还为您编写了一个与之相同的方法示例,该方法可以返回命令。好的,我正在测试您的代码,但我认为描述符有时可能为null。因此,我添加了if(描述符!=null)和if(descriptor.GetValue(value)!=null)GetProperties不应返回null,否则所有的示例都会在每个人都使用它时被破坏。描述符.GetValue(value)可能会返回null,因此可能使用String.Format(“{0}”,描述符.GetValue(value))会更好,那么值应该是“”。如果要省略值为“”的字段然后确保首先检查值。我无法使用空值测试代码。它不断给我错误。因此我只创建了一个包含所有字段值的数据库行。然而,答案很好。您的算法在速度/效率测试(如上)中排名第二,只花了700万纳秒。高亮显示。选择(pi=>new{Name=pi.Name,Value=pi.GetValue(myObj,null.ToString()})---对象未设置为引用。我添加了ToString,因为我不需要字典。但是,如果数据库字段为空/空,则会出现此对象未设置为引用的问题。这里是最快算法的赢家。很抱歉,我无法确定谁的答案最好。所有答案都是
public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes)
{
   RouteValueDictionary dictionary = new RouteValueDictionary();
  if (htmlAttributes != null)
  {
     foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes))
     {
            dictionary.Add(descriptor.Name.Replace('_', '-'), descriptor.GetValue(htmlAttributes));
       }
 }
    return dictionary;
 }
    public static Dictionary<string, string> ObjectToDictionary(object value)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        if (value != null)
        {
            foreach (System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(value))
            {
                if(descriptor != null && descriptor.Name != null)
                {
                     object propValue = descriptor.GetValue(value);
                     if(propValue != null)
                          dictionary.Add(descriptor.Name,String.Format("{0}",propValue));
            }
        }
        return dictionary;
    }
var myDict = myObj.ToDictionary(); //returns all public fields & properties
public static class MyExtensions
{
    public static Dictionary<string, object> ToDictionary(this object myObj)
    {
        return myObj.GetType()
            .GetProperties()
            .Select(pi => new { Name = pi.Name, Value = pi.GetValue(myObj, null) })
            .Union( 
                myObj.GetType()
                .GetFields()
                .Select(fi => new { Name = fi.Name, Value = fi.GetValue(myObj) })
             )
            .ToDictionary(ks => ks.Name, vs => vs.Value);
    }
}