【问题标题】:How to set ExpandoObject's dictionary as case insensitive?如何将 ExpandoObject 的字典设置为不区分大小写?
【发布时间】:2011-12-07 06:49:46
【问题描述】:

给出下面的代码

dynamic e = new ExpandoObject();
var d = e as IDictionary<string, object>;
for (int i = 0; i < rdr.FieldCount; i++)
   d.Add(rdr.GetName(i), DBNull.Value.Equals(rdr[i]) ? null : rdr[i]);

有没有办法让它不区分大小写,所以给定字段名称employee_name

e.Employee_name 和 e.employee_name 一样有效

似乎没有明显的方法,也许是 hack ?

【问题讨论】:

    标签: c# .net visual-studio-2010 dynamic expandoobject


    【解决方案1】:

    我一直在使用这个不区分大小写的“Flexpando”类(用于灵活扩展)。

    它类似于Darin's MassiveExpando 答案,因为它为您提供字典支持,但通过将其公开为一个字段,它不必为 IDictionary 实现 15 个左右的成员。

    public class Flexpando : DynamicObject {
        public Dictionary<string, object> Dictionary
            = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
    
        public override bool TrySetMember(SetMemberBinder binder, object value) {
            Dictionary[binder.Name] = value;
            return true;
        }
    
        public override bool TryGetMember(GetMemberBinder binder, out object result) {
            return Dictionary.TryGetValue(binder.Name, out result);
        }
    }
    

    【讨论】:

    • 我喜欢简洁,但觉得应该对内部进行更多控制。也许有两个构造函数,一个空的,默认为您在此处拥有的,另一个采用 IDictionary,任一构造函数都设置 Dictionary 字段,我将使用私有 setter 将其更改为公共属性。
    【解决方案2】:

    您可以签出Massive'sMassiveExpando 实现,它是不区分大小写的动态对象。

    【讨论】:

    • 有趣,不知道这个巨大的分支,自 2 月以来一直没有更新,所以会研究差异,谢谢!
    【解决方案3】:

    更多的是好奇而不是解决方案:

    dynamic e = new ExpandoObject();
    var value = 1;
    var key = "Key";
    
    var resul1 = RuntimeOps.ExpandoTrySetValue(
        e, 
        null, 
        -1, 
        value, 
        key, 
        true); // The last parameter is ignoreCase
    
    object value2;
    var result2 = RuntimeOps.ExpandoTryGetValue(
        e, 
        null, 
        -1, 
        key.ToLowerInvariant(), 
        true, 
        out value2);  // The last parameter is ignoreCase
    

    RuntimeOps.ExpandoTryGetValue/ExpandoTrySetValue 使用ExpandoObject 的内部方法,可以控制区分大小写。 null, -1,参数取自ExpandoObject内部使用的值(RuntimeOps直接调用ExpandoObject的内部方法)

    记住这些方法是This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.

    【讨论】:

    • obsolete 不能在 .net 4 msdn.microsoft.com/en-us/library/dd782193.aspx中编译
    • @Kumar 我必须说实话......是的,我已经在 Visual Studio 2010 上测试了代码并且它有效。只是为了确定今天早上我再次测试它并且它有效:-)有趣的是ExpandoTryGetValueExpandoTrySetValue在我的计算机上没有标记为过时,所以我没有收到任何警告。
    • 嗯,有趣,不知道这里有什么不同!我无法编译,所以去寻找答案并找到了 msdn 页面!我在xp sp3上有vs2010 Ultimate sp1!这台电脑上也没有测试版或任何东西,也不熟悉 .net 4 sp1 或预览版,有什么想法吗?
    • @Kumar 在此处使用 xp sp3 上的 vs 2010 pro,所以这不是问题。而且我没有 .NET 4.5 或类似的东西。啊。我的运行时版本是 v4.0.30319(我在 Visual Studio 中查看了 Microsoft.CSharp 参考资料)... MMmh... 您是否安装了异步 ctp 或 mvc 3.0?如果我没记错的话,他们会修改运行时
    【解决方案4】:

    另一种解决方案是通过从System.Dynamic.DynamicObject 派生并覆盖TryGetValueTrySetValue 来创建类似ExpandoObject 的类。

    【讨论】:

      【解决方案5】:
      public static class IDictionaryExtensionMethods
      {
        public static void AddCaseInsensitive(this IDictionary dictionary, string key, object value)
        {
          dictionary.Add(key.ToUpper(), value);
        }
      
        public static object Get(this IDictionary dictionary, string key)
        {
          return dictionary[key.ToUpper()];
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-02-18
        • 2018-12-30
        • 1970-01-01
        • 2017-12-01
        • 1970-01-01
        • 2010-11-01
        相关资源
        最近更新 更多