如鹏网.Net基础2 第五章:.Net常用基本类库

重点知识:

1、String常用方法:Contains、Split、StartsWith、EndsWith、IndexOf、SubString、Replace、Trim;判断一个字符串是null或者空的简单方法String.IsNullOrEmpty;

2、String s1=null;String s2="";String s3="  ";的区别是什么?

3、StringBuilder和String的区别是什么?

4、int可以为null吗?如果想表示可以为null的整数,应该怎样表示?

5、try……catch;try……finally;try……catch……finally;catch中的代码什么时候执行;finally中的代码什么时候执行;

6、如何判断一个文件是否存在;最简单的读取一个文本文件所有内容的方法是什么,有什么缺点?

7、如何遍历一个文件夹下所有的jpg图片?

8、FileStream和StreamReader/StreamWriter的区别是什么?

9、如何使用StreamReader读取一个文本文件?如果出现乱码是什么问题?

10、使用FileStream和StreamReader/StreamWriter应该如何正确的释放资源?

11、如何使用FileStream拷贝一个文件?

12、泛型List有哪些常见操作?泛型Dictionary有哪些常见操作?

13、什么样的对象可以使用foreach进行遍历?

------------------------------------------------

第 1 节 String常用方法1

  成员方法:

  bool Contains(String str):判断字符串对象是否包含给定的字符串。

  bool StartsWith(String str):判断字符串对象是否以给定的字符串开始。

  bool EndsWith(String str):判断字符串对象是否以给定的字符串结束。

        /*string s1 = "Hello";
            Console.WriteLine(s1.Contains("el"));
            Console.WriteLine(s1.Contains("abc"));
             */
            /*
            Console.WriteLine(s1.StartsWith("He"));
            Console.WriteLine(s1.StartsWith("he"));
             */
 
            /*
            string s = "http://www.rupeng.com";
            if (s.StartsWith("https://") &&
                (s.EndsWith(".com") || s.EndsWith(".cn")))
            {
                Console.WriteLine("合法网址");
            }
            else
            {
                Console.WriteLine("非法网址");
            }*/
            /*
            string email = "3333@173.com";
            string username = "***万岁";
            if (email.EndsWith("@qq.com"))
            {
                Console.WriteLine("本站不支持QQ邮箱");
                Console.ReadKey();
                return;
            }
            if (username.Contains("* * *") || username.Contains("***"))
            {
                Console.WriteLine("用户名请勿使用敏感词汇");
                Console.ReadKey();
                return;
            }*/

  案例:判断是否是网址:以http:// 开头,以 .com   或 .cn结尾。

  *:好的编程习惯非常重要!

------------------------------------------------
第 2 节 String常用方法2

  int Length:获取字符串的长度属性

  char ch = s[3];

  int IndexOf(int ch):返回指定字符在此字符串中第一次出现的索引

  int IndexOf(String str):返回指定字符串在此字符串中第一次出现的索引

  LastIndexOf:最后一次出现的位置。

  String Substring(int start):截取字符串。返回从指定位置开始截取后的字符串。

  String substring(int start,int length)截取字符串。返回从指定位置开始截取指定长度length的字符串。

           string s1 = "hellooabcdaabe";
            int i = s1.IndexOf('l');
            Console.WriteLine(i);
            Console.WriteLine(s1.IndexOf("ab"));
            Console.WriteLine(s1.LastIndexOf('l'));
 
            string s2 = s1.Substring(4);
            Console.WriteLine(s2);
            Console.WriteLine(s1.Substring(4,3));    

  案例获取一个文件名的名称和扩展名部分:

            string filename = "[ADS-118]林志aaaaaa玲.avi";//
            int dotIndex = filename.IndexOf('.');//3
            string name = filename.Substring(0, dotIndex);
            Console.WriteLine(name);
            string ext = filename.Substring(dotIndex + 1);
            Console.WriteLine(ext);

 练习:从http://www.rupeng.com:8090/a.htm获得域名、端口号

------------------------------------------------
第 3 节 String常用方法3 

  String ToLower():把字符串变成小写(获得一个新的全小写的字符串返回);String ToUpper():把字符串变成大写 

  String Replace(char oldChar,char newChar):用新的字符去替换指定的旧字符,返回一个新的字符串;String Replace(String oldStr,String newStr):用新的字符串去替换指定的旧字符串

  String是不可变的(是指这个字符串对象不可改变,无法修改字符串的内容),因此上面的操作都是生成新的字符串对象,要用返回值去取新的字符串。

     string s1="Hello"; s1.ToLower(); //s1还是“Hello” ;

     只有重新指向才会改变:s1=s1.ToLower();

 

案例:给一个全班数学考试成绩的字符串“50, 80,33,58,99,  82”,成绩用逗号分隔,有的成绩中可能有空格,有的地方逗号是英文、有的逗号是中文。统计班级的平均分。

------------------------------------------------
第 4 节 String常用方法4

  String trim():去除字符串两端空格, Trim(params char[] trimChars)去掉两端的给定字符。 TrimEnd、 TrimStart

  String[] Split(...):重载方法很多,字符串按照分隔符切割。

  要求:写代码就是精益求精,在不降低可读性的情况下,不断精减代码。

  练习:成绩字符串“34,45,65, 54,76,43,”,求平均分。

   int/int=int;      int*1.0/int=double;

------------------------------------------------
第 5 节 String常用方法5

 string静态方法:

   bool IsNullOrEmpty(string value):判断字符串是否为null或者是空字符串;

   bool Equals(string a, string b, StringComparison. OrdinalIgnoreCase): StringComparison. OrdinalIgnoreCase不区分大小写比较。案例:验证码

   string Join(string separator, params string[] value)把一个数组(集合)用分隔符separator连接为一个字符串。

     if(str==null||str.Length<=0) //短路

    记忆方法:使用案例记忆知识点(知识点的使用场景),而不是单独死记知识点。

------------------------------------------------
第 6 节 案例:小冰聊天机器人

  功能:

    1. 你好  好你妹

    2.名字   我叫小冰

    3.男的 女的   人家是女孩子

    4.男朋友    人家还小,不考虑

    5.其他  呵呵

    6.唱(歌):播放音乐 SoundPlayer类

  解决安全:属性 通用属性 当前选择内容

  keyPress事件中:

    txtRecord.AppendText(Convert.ToString(e.KeyChar));  

    //我在几点几分说什么内容

    //小冰回复什么

        e.keyChar=='\r'

------------------------------------------------
第 7 节 案例:表白神器

用Timer,设定Interval(每隔多少毫秒调用一次Tick事件)。

设一个100ms执行一次的定时器,从预定义的“全部表白文本”,每次取在当前文本框文本的长度,然后从“全部表白文本”取第“当前文本框文本的长度”个字符插入到TextBox(设定为多行、Append()附加),当输出完毕Timer.Enabled=false停止定时器。

  Timer  

------------------------------------------------
第 8 节 StringBuilder

  1、使用反编译发现

  String s7="111"+"222"+"333"+"444"+"555"  

  会被优化为  String s7 = "111222333444555";

  但是String s6 = s1 + s2 + s3 + s4 + s5;就没那么幸运了,每次+都会生成一个String对象,当连接字符串比较多的时候就会产生临时字符串对象

  2、使用StringBuilder拼接字符串则不会有临时字符串对象的问题:

    StringBuilder sb = new StringBuilder();

    sb.Append(s1);

    sb.Append(s2);

    sb.Append(s3);

  因为Append方法把this返回了,还可以sb.Append(s1).Append(s2).Append(s3);

  最后使用String s = sb.ToString()一次性生成拼接结果字符串即可

       sb.AppendLine(33);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace CommonClassTest2
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
            string s1 = "aaa" +
                +"aaaaa"+"bbb";
            Console.WriteLine(s1);
             */
            string s1 = "aaa";
            string s2 = "bbb";
            string s3 = "ccc";
            string s4 = "ddd";
            string s5 = "afadsf";
            string s6 = s1 + s2 + s3 + s4 + s5;
 
            StringBuilder sb = new StringBuilder();
            /*
            sb.Append(s1);
            sb.Append(s2);
            sb.Append(s3);
            sb.Append(s4);
            sb.Append(s5);
            sb.Append(33);*/
           sb.Append(s1).Append(s2).Append(s3).Append(s4).Append(s5);
           sb.AppendLine("hello");
           sb.AppendLine("afasdfads");
 
            string s7 = sb.ToString();
            Console.WriteLine(s7);
 
            Person p1 = new Person();
            p1.Eat().Sleep().Dota();//链式编程 Jquery
            Console.ReadKey();
        }
    }
 
    class Person
    {
        public Person Eat()
        {
            Console.WriteLine("吃饭");
            return this;
        }
        public Person Sleep()
        {
            Console.WriteLine("睡觉");
            return this;
        }
        public Person Dota()
        {
            Console.WriteLine("打Dota");
            return this;
        }
    }
}

------------------------------------------------
第 9 节 可空的int(值类型)

  int等是值类型,不能为null。有时想表达“不知道数字是多少”的时候,用int任何值表示都不合适。

  C#中可以用“int?”表示“可空的int”。注意类型转换:

  int? i1=5;

  if(i1!=null)

  {

      int i= (int)i1;

  }

  也可以通过i1.HasValue判断是否为null、i1.Value来获得值。

int? i = null;
int? i2 = 3;
if (i == null)
{
    Console.WriteLine("i为null");
}
if (i2 != null)//i2.HasValue
{
    //i2++;
    i2 = i2 + 3;
    //int i3 = i2;//把可能为null的int?赋值给
    //一定不为null的int
    int i3 = (int)i2;//i2.Value
    Console.WriteLine(i2);
}
long? l = null;

 

------------------------------------------------
第 10 节 案例:LED时钟

.Net使用DateTime类表示时间数据类型。DateTime属于结构体,因此也是值类型。

DateTime.Now当前时间;DateTime.Today当前日期。

可以通过Year、Month、Hour 等属性得到日期的年、月、小时等部分;也可以用构造函数根据给定的时间创建一个对象。

DateTime dt = DateTime.Now;
Console.WriteLine(dt);
Console.WriteLine(DateTime.Today);
 
DateTime dt2 = new DateTime(2019, 9, 10);
Console.WriteLine(dt2);
 
Console.WriteLine(dt.Year);
Console.WriteLine(dt.DayOfYear);
Console.WriteLine(dt.Second);

   练习1:LED时钟

   练习2:实现整点报时“北京时间18点整”  

   练习3:把数字转换为中文金额数字 123 ->壹佰贰拾叁元整  

------------------------------------------------
第 11 节 异常的概念和捕获

1、异常的根类为Exception。异常类一般都继承自Exception

2、异常的捕获

try
{
    String s = null;
    s.ToString();
}
catch (NullReferenceException ex)
{
    Console.WriteLine("为空"+ex.Message);
} 

e就是发生异常的异常类对象,变量名只要不冲突就任意。

3、在异常处理中,一旦try里面有问题了。放弃try代码块中之后的代码,直接跳到catch里面执行。如果try代码后还有代码,则处理完catch后还会继续执行。

------------------------------------------------
第 12 节 try finally

4、多个异常的处理 

try
{
    int a = 10;
    int b = 0;
    Console.WriteLine(a / b);
    int[] arr = { 1, 2, 3 };
    Console.WriteLine(arr[3]);
}
catch (DivideByZeroException ae)
{
    Console.WriteLine("除数不能为0");
}
catch (IndexOutOfRangeException ae)
{
    Console.WriteLine("数组越界异常");
}

 可以catch住父类异常,这样就可以抓住所有子类异常了,但是强烈不建议大家这样做,特别是不要没理由的catch(Exception ex)

 如果不知道如何处理异常,就不要轻易的catch 。

 5、好的异常处理习惯:

不要只是把异常catch住什么都不做或者只是打印一下,这不是正常的“异常处理”。

不知道怎么处理就不要catch,出错比“把错误藏起爱”好。这样以为“不会出错了”,其实是把异常“吃掉了”,会让程序陷入逻辑混乱状态,要科学合理的处理异常(以后经常用就明白了)。

try{
//有可能有问题代码
}catch(异常类型 异常变量){
//处理方式
}finally{
//无论“有可能有问题代码”是否出错都要执行的代码
}

 finally中一般进行资源的回收等

可以只有try{}finally{},没有catch,一般发生在不知道如何处理异常的情况下,回收资源

如果不知道怎么处理,就不要catch。

不允许以下代码:

try{
//代码
}catch(Exception ex){
//垃圾代码,抓住异常后,是必须要处理掉的,而不是再抛出一个异常
  throw ex;    
}

------------------------------------------------

第 13 节 File类(静态方法),对文件(夹)进行处理,System.IO;

File是静态类(无法被new)中的主要静态方法:

void Delete(string path):删除文件;

bool Exists(string path):判断文件是否存在;

string[] ReadAllLines(string path):将文本文件中的内容读取到string数组中;

string ReadAllText(string path):将文本文件读取为一个字符串

void WriteAllLines(string path, string[] contents):将string[]写入到文件中;

void WriteAllText(string path, string contents):将字符串contents写入到文件path中。

AppendAllText:向文件中附加内容;Copy复制文件;Move移动文件

/*
if(File.Exists(@"d:\temp\a.pnproj"))
{
    File.Delete(@"d:\temp\a.pnproj");
}*/
 
/*
string[] lines = File.ReadAllLines(@"d:\temp\my.txt",
    Encoding.Default);
for (int i = 0; i < lines.Length; i++)
{
    Console.WriteLine("第"+i+"行:"+lines[i]);
}*/
/*
String s = File.ReadAllText(@"d:\temp\my.txt");
Console.WriteLine(s);
    */
// File.WriteAllText(@"d:\temp\test.txt", "如鹏网欢迎你");
//File.AppendAllText(@"d:\temp\test.txt", "afasfsafadsf");

------------------------------------------------
第 14 节 Directory类

CreateDirectory(string path):创建文件夹全路径

void Delete(string path, bool recursive):删除文件夹path, recursive表示是否也删除子文件及子文件夹。如果文件夹不为空, recursive=false,则抛异常;

bool Exists(string path):判断文件夹是否存在

EnumerateFiles、 EnumerateDirectories遍历文件和文件夹;

// Directory.CreateDirectory(@"d:\temp\a\b\c");
//Directory.Delete(@"d:\temp\");//目录=文件夹,只能删除空文件夹
//Directory.Delete(@"D:\temp\redissessiontest", true); //递归删除
 
IEnumerable<string> files1 =
    //Directory.EnumerateFiles(@"d:\temp");
    //Directory.EnumerateFiles(@"d:\temp","*.*",SearchOption.AllDirectories);
    Directory.EnumerateFiles(@"d:\temp", "*.avi", SearchOption.AllDirectories);
IEnumerator<string> filesEnum1 = files1.GetEnumerator();
while (filesEnum1.MoveNext())//在结果中向下移动一条
{
    Console.WriteLine(filesEnum1.Current);//获得当前结果
}

 

------------------------------------------------
第 15 节 FileStream写入

File类提供了读写文本文件的方法,但是对于大文件不能用它提供的方法,占内存,需要一种“流式处理”的方法。

.NET将IO操作(文件、网络等)简化成流模型Stream,是抽象类,网络、文件、加密等都是不同的子类,最常用的子类是FileStream,MemoryStream等。

在使用Stream的时候虽然可以写成:FileStream fs=new FileStream(……),但是Stream fs=new FileStream(……)更好,在使用的变量类型提供的操作能满足的前提下,尽可能使用父类、接口声明变量。

FileStream fs = new FileStream(@"d:\temp\1.txt",FileMode.Create);
byte[] bytes1 = Encoding.Default.GetBytes("如鹏网你好\r\n");
//任何数据都是以byte为单位写入的。GetBytes获得字符串的byte表示形式
fs.Write(bytes1,0,bytes1.Length);
 
byte[] bytes2 = Encoding.Default.GetBytes("www.rupeng.com");
fs.Write(bytes2,0,bytes2.Length);//在上一个Write的结尾继续写入
fs.Close();//一定要用完了关闭

Stream写入的单位是byte(字节),char转换为byte时候,一个英文char转换为一个byte(对应的ASCII码),一个中文char转换为两个byte(*采用GBK编码时),试着输出bytes的长度。

采用Default、UTF8、UTF32得到的字符串的byte[]长度不一样,因此说明不同类型编码在计算机中存储的不一样。用什么编码写入就用什么编码读取,否则会有乱码的问题。

不要往C盘写,因为Win7、Win8默认普通程序没有权限读写C盘。

------------------------------------------------
第 16 节 FileStream资源正确的释放Dispose

  如果发生异常,fs就不能正常close,fs用完必须Close;

  资源回收最好用Dispose()方法。

  可以用:

    FileStream fs=null;//避免来不及创建就出异常了,必须初始化

    try{

    //fs有可能成为没有被赋值的变量

    fs=new FileStream(.....);

    ......

    } finally{if(fs!=null){fs.Dispose();}}

  所有实现IDisposable接口的都可以调用Dispose()方法。

 

  

------------------------------------------------
第 17 节 using简化资源释放

using()using(){}

每次资源关闭都要写这么一堆代码,C#中提供了using语法,对于一个实现IDisposable接口的对象,进行资源释放。

定义一个实现了IDisposable接口的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace IOTest2
{
    class MyFileStream:IDisposable
    {
        public MyFileStream()
        {
            //throw new Exception("初始化出错");
        }
 
        public void Write(int i)
        {
            throw new Exception("Write出错");
            Console.WriteLine("写入了"+i);
        }
 
        public void Dispose()
        {
            Console.WriteLine("Dispose被调用了,开始释放资源,虽然没什么可释放的");
        }
    }
}

使用:

using (MyFileStream fs1 = new MyFileStream())
{
    using (MyFileStream fs2 = new MyFileStream())
    {
        fs2.Write(333);
        fs1.Write(5);
    }
}

可以同时声明多个资源:

using (MyFile f1 = new MyFile())

using (MyFile f2 = new MyFile())

{

}

using其实就是编译器简化的try……finally操作,通过ILSpy反编译成IL可以看出来。

using只是try……finally,如果需要catch,只要catch就是了。

using作用域就是{}中,,using只是finally,如果要catch,还是要try catch。

 

------------------------------------------------
第 18 节 FileStream读取文件以及乱码问题

using (FileStream fs = new FileStream(@"D:\temp\1.txt", FileMode.Open))
{
 
    byte[] bytes = new byte[4];
    //fs.Read(bytes, 0, bytes.Length);//每次读取4个字节,下次Read的时候再读取最多4个byte
    //返回值为真正读取的字节数
    int len;
    /*
    len = fs.Read(bytes, 0, bytes.Length);
    Console.WriteLine(len);
    len = fs.Read(bytes, 0, bytes.Length);
    Console.WriteLine(len);
    len = fs.Read(bytes, 0, bytes.Length);
    Console.WriteLine(len);
        */
 
    //判断是否已经读到了最后
    while ((len = fs.Read(bytes, 0, bytes.Length)) > 0)
    {
        //Console.WriteLine(len);
        //把byte数组转化为字符串
        //string s = Encoding.Default.GetString(bytes);
        string s = Encoding.Default.GetString(bytes, 0, len);
        Console.WriteLine(s);
    }
 
}

 字节流(FileStream)不适合读取内容中包含文本的文档,容易造成数据错乱(byte[]中含有一半的汉字),要用后面讲的StreamReader。

 

------------------------------------------------
第 19 节 FileStream实现文件的拷贝

Stopwatch sw = new Stopwatch();
sw.Start();
using (Stream inStream = 
    new FileStream(@"d:\temp\DevCpp.zip", FileMode.Open))
using (Stream outStream =
    new FileStream(@"e:\temp\1.zip", FileMode.Create))
{
    //byte[] bytes = new byte[100];//100字节
    //1024字节=1k,1024k=1m
    byte[] bytes = new byte[1024*50];//1M(一般在几M范围)
    //缓冲区(buffer)的大小:过小:降低速度;过大:占用内存
    int len;
    while ((len = inStream.Read(bytes, 0, bytes.Length)) > 0)
    {
        outStream.Write(bytes, 0, len);//类似于GetString
    }
}
sw.Stop();
Console.WriteLine("拷贝完成,耗时" + sw.ElapsedMilliseconds+"毫秒");

 

------------------------------------------------
第 20 节 封装Copy流的方法并开发下载器

封装一个方法void copy(Stream inStream,Stream outStream,int bufferSize)用来把inStream复制到outStream中,

缓冲区大小为bufferSize。要检查参数合法性(是否为null,bufferSize是否在合理范围内)

再提供一个使用默认缓冲区大小的copy的重载,复习重载。

 

------------------------------------------------
第 21 节 StreamReader和StreamWriter

直接用Stream进行文本文件的读写会比较麻烦,因为要考虑文件的编码、中文字符等的问题。

StreamReader、StreamWriter是用来读写字符流(character stream)的类,会帮着自动处理麻烦的问题。

using (Stream outStream = 
    new FileStream(@"d:\temp\1.txt", FileMode.Create))
using(StreamWriter sw = 
    new StreamWriter(outStream,Encoding.Default))
{
    sw.Write("你好a如鹏网");
    sw.WriteLine("hehe");
    sw.WriteLine("1111");
}
using (Stream inStream = new FileStream(@"d:\temp\1.txt",
    FileMode.Open))
using (StreamReader reader =
    new StreamReader(inStream, Encoding.Default))
{
    /*
    string s = reader.ReadToEnd();
    Console.Write(s);*/
    /*
    string s1 = reader.ReadLine();
    Console.WriteLine(s1);
 
    string s2 = reader.ReadLine();
    Console.WriteLine(s2);
        */
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        Console.WriteLine(line);
    }
}

   编码:

  由于历史原因,汉字等如何在计算机中以字节存储存在着多种标准,最学见的有GB2312(国家标准,表示汉字)、

GBK(GB2312的扩展,还能表示繁体字等)、UTF-8(国际标准),UTF-16等。

  用什么编码保存就用什么编码读取,就不会乱码!

  StreamWriter构造函数决定(为什么?)new StreamWriter(outStream,Encoding.UTF8).

  读取的编码由StreamReader构造函数决定。

 

------------------------------------------------
第 22 节 泛型List

1、数组长度是固定的,List<T>可以动态增删内容。List<T>是泛型的,可以在声明的时候指定放什么类型的数据。

List<int> list = new List<int>();

list.Add(1);

list.Add(2);

list.AddRange(new int[] { 1, 2, 3, 4, 5, 6 });

list.AddRange(list);//另一个list

 

2、如何遍历?

for (int i = 0; i < list1.Count; i++)

{

    int num = list1[i];

    Console.WriteLine(num);

}

 

3、int[] nums = list.ToArray(); //List泛型集合可以转换为数组

List<string> listStr = new List<string>();

string[] str = listStr.ToArray();

------------------------------------------------
第 23 节 字典Dictionary

Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("zs", "张三");
dict.Add("ls", "李四");
dict.Add("ww", "王五");
dic["ls"] = "小赵";
String s = dict["ww"];
dict.ContainsKey();
 
//<k,v>k是键的类型(根据谁查),v是值的类型(查什么)
/*
Dictionary<string, int> dict = new Dictionary<string, int>();
dict.Add("abc", 123);//往字典中放数据(k,v)
dict.Add("aaa", 222);
int i = dict["abc"];//根据key从字典中查数据
Console.WriteLine(i);
Console.WriteLine(dict["aaa"]);*/
 
/*
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("zs","张三");
dict.Add("ls", "李四");
// dict.Add("ls","李斯");// 如果key已经存在,则抛异常
dict["ls"] = "李斯";//如果不存在key,则添加;如果存在则替换
dict["ww"] = "王五";
             
string name = dict["ls"];
Console.WriteLine(dict.ContainsKey("ls"));
Console.WriteLine(dict.ContainsKey("abc"));
Console.WriteLine(name);

  字典Dictionary 内部使用哈希算法

 

------------------------------------------------
第 24 节 案例:火星文翻译器

  就是(类似)替换,两个数组长度一样

作业 :汉字拆字

------------------------------------------------
第 25 节 ForEach

注意:使用MoveNext()的方法讲解IEumerable只是在讲原理,实际开发中还是使用foreach

 

除了使用for遍历,实现了IEumerable接口的对象还可以使用foreach遍历:

string[] strs = { "fasdfa","fsadf","222"};
foreach (string s in strs)
{
    Console.WriteLine(s);
}

List<T>、 Dictionary<K,V> 等一切实现了IEnumerable接口的对象都可以:

Dictionary<string, object> dict = new Dictionary<string, object>();
dict["rupeng"] = 888;
dict["sina"] = "hehe";
dict["baidu"] = true;
foreach (KeyValuePair<string, object> kv in dict)
{    
   Console.WriteLine(kv.Key+"="+kv.Value);
}

 如鹏网:http://www.rupeng.com

posted @ 2016-03-03 16:47  小居工作室  阅读(439)  评论(0编辑  收藏  举报