VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 953|回复: 6

关于配置文件中的NameValueCollection的一点疑惑

[复制链接]

1

主题

2

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
发表于 2020-1-22 11:40:01 | 显示全部楼层 |阅读模式
很早的时候就开始写一个configuration,但是发现net自带的configuration有些地方让人搞不明白

看下面的代码  app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
   
    <section name="myCustomerSectionA" type="System.Configuration.NameValueSectionHandler"/>
   
    <section name="myCustomerSectionB" type="ConfigurationDemoII.CustomerSectionHandlers,ConfigurationDemoII" />
   
  </configSections>
  <myCustomerSectionA>
    <add key="myKeyA" value="myKeyAValueA" />
    <add key="myKeyA" value="myKeyAValueB" />
    <add key="myKeyB" value="myKeyBValueA" />
    <add key="myKeyB" value="myKeyBValueB" />
  </myCustomerSectionA>
  <myCustomerSectionB>
    <add key="myKeyA" value="myKeyAValueA" />
    <add key="myKeyA" value="myKeyAValueB" />
    <add key="myKeyB" value="myKeyBValueA" />
    <add key="myKeyB" value="myKeyBValueB" />
  </myCustomerSectionB>
  
</configuration>

app.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Xml;
using System.Configuration;
namespace ConfigurationDemoII
{
    class Program
    {
        static void Main( string[] args )
        {
            try
            {
                TestSysNameValueCollection();
                Console.WriteLine( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
                TestMyNameValueCollection();
            }
            catch( Exception ex )
            {
                Console.WriteLine( ex.Message );
                Console.WriteLine( ex.StackTrace );
            }
        }
        private static void TestSysNameValueCollection()
        {
            NameValueCollection nvc = (NameValueCollection)ConfigurationManager.GetSection( "myCustomerSectionA" );
            foreach( string key in nvc.AllKeys )
            {
                Console.WriteLine( key );
                Console.WriteLine( nvc[key] );
            }
        }
        private static void TestMyNameValueCollection()
        {
            NameValueCollection nvc = (NameValueCollection)ConfigurationManager.GetSection( "myCustomerSectionB" );
            foreach( string key in nvc.AllKeys )
            {
                Console.WriteLine( key );
                Console.WriteLine( nvc[key] );
            }
        }
    }
    class CustomerSectionHandlers : IConfigurationSectionHandler
    {
        #region IConfigurationSectionHandler 成员
        object System.Configuration.IConfigurationSectionHandler.Create( object parent, object configContext, System.Xml.XmlNode section )
        {
            NameValueCollection col = new NameValueCollection();
            foreach( XmlNode childNode in section.ChildNodes )
            {
                XmlElement root = (XmlElement)childNode;
                if( root.Name == "add" )
                {
                    string key = root.GetAttribute( "key" );
                    string value = root.GetAttribute( "value" );
                    col.Add( key, value );
                }
                else if( root.Name == "remove" )
                {
                }
                else if( root.Name == "clear" )
                {
                }
            }
            return col;
        }
        #endregion
    }
}




运行的结果  

myKeyA
myKeyAValueB
myKeyB
myKeyBValueB
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
myKeyA
myKeyAValueA,myKeyAValueB
myKeyB
myKeyBValueA,myKeyBValueB
Press any key to continue . . .

能看到什么不同么, Sys自带的namevaluecollection好像把后面新加入的同一个key的信息冲掉了,如果是configuration本身就是这么设计的,那么为何要用NameValueCollection这个容器呢?

我在cnblog的几篇介绍configuration的文章中并没有找到相关的信息  http://msdn.microsoft.com/msdn-online/shared/components/ratings/ratings.aspx?ContentID=_978498&HideDiscuss=1里面也没有这一块类似的介绍

OK, 打开Refelect看看吧  哦,  
internal static object CreateStatic(object parent, XmlNode section, string keyAttriuteName, string valueAttributeName)
{
      ReadOnlyNameValueCollection collection1;
      if (parent == null)
      {
            collection1 = new ReadOnlyNameValueCollection(new CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture), new CaseInsensitiveComparer(CultureInfo.InvariantCulture));
      }
      else
      {
            ReadOnlyNameValueCollection collection2 = (ReadOnlyNameValueCollection) parent;
            collection1 = new ReadOnlyNameValueCollection(collection2);
      }
      HandlerBase.CheckForUnrecognizedAttributes(section);
      foreach (XmlNode node1 in section.ChildNodes)
      {
            if (!HandlerBase.IsIgnorableAlsoCheckForNonElement(node1))
            {
                  if (node1.Name == "add")
                  {
                        string text1 = HandlerBase.RemoveRequiredAttribute(node1, keyAttriuteName);
                        string text2 = HandlerBase.RemoveRequiredAttribute(node1, valueAttributeName, true);
                        HandlerBase.CheckForUnrecognizedAttributes(node1);
                        collection1[text1] = text2;
                  }
                  else
                  {
                        if (node1.Name == "remove")
                        {
                              string text3 = HandlerBase.RemoveRequiredAttribute(node1, keyAttriuteName);
                              HandlerBase.CheckForUnrecognizedAttributes(node1);
                              collection1.Remove(text3);
                              continue;
                        }
                        if (node1.Name.Equals("clear"))
{ HandlerBase.CheckForUnrecognizedAttributes(node1);
                              collection1.Clear();
                              continue;
                        }
                        HandlerBase.ThrowUnrecognizedElement(node1);
                  }
            }
      }
      collection1.SetReadOnly();
      return collection1;
}


ReadOnlyNameValueCollection 这个东西sdk里面没有介绍 HandlerBase 这个玩意也没有深入研究过,晕


还是偷懒一下,等着牛人来回答吧

过往的牛人, 请留下高见
回复

使用道具 举报

0

主题

32

帖子

22.00

积分

新手上路

Rank: 1

积分
22.00
发表于 2020-2-2 14:54:02 | 显示全部楼层
楼主发现了一个现象,不过我看不到疑惑在哪儿。
如果是自己来写NameValueSectionHandler,要实现相同的效果,只保留key相同的最后一个value,当然不难。
NameValueCollection不能有相同的key,所以add是把key相同的value加到一起了。(楼主的实现)
至于framework的NameValueSectionHandler的具体实现,没去深究,因为要达到同样的效果也不难,省了这功夫。

---个人观点,不喜勿怪。
回复

使用道具 举报

1

主题

2

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
 楼主| 发表于 2020-2-19 17:45:01 | 显示全部楼层
To  江南小色

我的疑惑是  既然 net自带的 Configuration 返回的是 NameValueCollection,那么它不应该是“只保留key相同的最后一个value”,因为namevaluecollection这个容器本身的特点就是一个key对应多个value, 他完全可以返回一个hashtable或者是别的容器,没有必要迷惑使用者啊,我想知道的是   是不是我写的代码有些地方没有注意才会造成这样的问题或者说是MS的BUG
回复

使用道具 举报

0

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
发表于 2020-3-5 17:15:01 | 显示全部楼层
在Collections下的hashtable是不允许有相同的key存在的,所以楼主这么用,应该很不地道,把value当key,key当value,可以在value不同的时候挡一下。
如果实在需要,则可以自己构造一个链式哈希表,在hashtable里放上ArrayList。
回复

使用道具 举报

0

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-3-7 09:30:01 | 显示全部楼层
Study
回复

使用道具 举报

0

主题

32

帖子

22.00

积分

新手上路

Rank: 1

积分
22.00
发表于 2020-3-20 18:15:01 | 显示全部楼层
NameValueCollection不能一个key对应多个value,是在Add(key,value)的时候,遇到相同的key,把value加到一起,用逗号分隔。
看它的count属性就知道了,并没有多。
回复

使用道具 举报

0

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-8-10 12:00:01 | 显示全部楼层
NameValueCollection 是可以一key 多value的

关键是调用的方法不同,结果不同。

如果是用nc.Add,是在同一个key的上面加值
如果是nc.Set/nc[] 是设定或者替换.

nc.Get / nc[] 是 返回字符串
nc.GetValue 是返回对应的多值数组

如果不能多value

象 ?method=post&method=get&method=head 这样的URL就没发解析了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表