public CsvConfigField Clone()
        {
            CsvConfigField temp = this.MemberwiseClone() as CsvConfigField;

            temp.Value = temp.Value.Clone();
            return(temp);
        }
        public void Read(TextReader reader)
        {
            Reset();
            try
            {
                CsvReader csvReader  = new CsvReader(reader, false);
                int       fieldCount = csvReader.FieldCount;

                bool hasKey   = false;
                int  keyIndex = -1;
                Dictionary <int, CsvValue.CsvValueType> typeDic = new Dictionary <int, CsvValue.CsvValueType>();

                bool hasName = false;
                Dictionary <int, string> nameDic       = new Dictionary <int, string>();
                Dictionary <int, bool>   buildIndexDic = new Dictionary <int, bool>();
                foreach (string[] strings in csvReader)
                {
                    //check fieldCount
                    if (strings.Length != fieldCount)
                    {
                        StringBuilder sb    = new StringBuilder();
                        bool          first = true;
                        foreach (string s in strings)
                        {
                            if (first)
                            {
                                sb.Append(s);
                                first = false;
                            }
                            else
                            {
                                sb.Append(",").Append(s);
                            }
                        }
                        throw new CsvException(string.Format("fields length error,{0}", sb.ToString()));
                    }

                    //set key
                    if (!hasKey)
                    {
                        for (int i = 0; i < fieldCount; i++)
                        {
                            string low = strings[i].ToLower();
                            if (!_typeDic.ContainsKey(low) && !_keyTypeDic.ContainsKey(low) && low.EndsWith("i"))
                            {
                                buildIndexDic.Add(i, true);
                                low = low.TrimEnd('i');
                            }
                            else
                            {
                                buildIndexDic.Add(i, false);
                            }

                            if (_typeDic.ContainsKey(low))
                            {
                                typeDic.Add(i, _typeDic[low]);
                            }
                            else if (_keyTypeDic.ContainsKey(low))
                            {
                                if (hasKey)
                                {
                                    throw new CsvException(string.Format("already has key{0}", low));
                                }
                                hasKey   = true;
                                keyIndex = i;
                                typeDic.Add(i, _keyTypeDic[low]);
                                _keyType = _keyTypeDic[low];
                            }
                            else
                            {
                                throw new CsvException(string.Format("error header:{0}", low));
                            }
                        }
                        hasKey = true;
                        continue;
                    }

                    //set names
                    if (!hasName)
                    {
                        for (int i = 0; i < fieldCount; i++)
                        {
                            string name = strings[i];
                            if (_fieldNames.Contains(name))
                            {
                                throw new CsvException(string.Format("same field name:{0}", name));
                            }
                            if (buildIndexDic[i])
                            {
                                _indexDic[name] = new Dictionary <CsvValue, List <CsvConfig> >();
                            }
                            nameDic.Add(i, name);
                            _fieldNames.Add(name);
                        }
                        hasName = true;
                        continue;
                    }

                    CsvConfig config = new CsvConfig();
                    for (int i = 0; i < fieldCount; i++)
                    {
                        string         value    = strings[i];
                        CsvValue       csvValue = new CsvValue(typeDic[i], value);
                        CsvConfigField field    = new CsvConfigField(i, i == keyIndex, buildIndexDic[i], nameDic[i],
                                                                     csvValue);
                        config.AddField(field);
                        if (buildIndexDic[i])
                        {
                            bool     alreadyContanValue = false;
                            CsvValue indexValue         = null;
                            foreach (KeyValuePair <CsvValue, List <CsvConfig> > pair in _indexDic[nameDic[i]])
                            {
                                if (pair.Key.Equals(csvValue))
                                {
                                    alreadyContanValue = true;
                                    indexValue         = pair.Key;
                                }
                            }
                            if (!alreadyContanValue)
                            {
                                _indexDic[nameDic[i]][csvValue] = new List <CsvConfig>();
                                _indexDic[nameDic[i]][csvValue].Add(config);
                            }
                            else
                            {
                                _indexDic[nameDic[i]][indexValue].Add(config);
                            }
                        }
                    }

                    CsvValue keyValue = new CsvValue(typeDic[keyIndex], strings[keyIndex]);
                    foreach (KeyValuePair <CsvValue, CsvConfig> pair in _configDic)
                    {
                        if (pair.Key.Equals(keyValue))
                        {
                            throw new CsvException(string.Format("already contains key :{0}", keyValue.Value));
                        }
                    }
                    _configDic.Add(keyValue, config);
                }
                if (!hasKey)
                {
                    throw new CsvException("miss key in header.");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                throw new CsvException(e.Message);
            }
        }