C#基础+高级

C#集合相关知识

C#里面Collection下面ArrayList

1、动态数组 Array List:
动态数组(ArrayList)代表了可被单独索引的对象的有序集合。它基本上可以替代一个数组。但是,与数组不同的是,
您可以使用索引在指定的位置添加和移除项目,动态数组会自动重新调整它的大小。它也允许在列表中进行动态内存
分配、增加、搜索、排序各项。

表列出了 ArrayList 类的一些常用的 属性:

属性 描述
Capacity 获取或设置 ArrayList 可以包含的元素个数。
Count 获取 ArrayList 中实际包含的元素个数。
IsFixedSize 获取一个值,表示 ArrayList 是否具有固定大小。
IsReadOnly 获取一个值,表示 ArrayList 是否只读。
IsSynchronized 获取一个值,表示访问 ArrayList 是否同步(线程安全)。
Item[Int32] 获取或设置指定索引处的元素。
SyncRoot 获取一个对象用于同步访问 ArrayList。

1、public virtual int Add( object value );
在 ArrayList 的末尾添加一个对象。

2、public virtual void AddRange( ICollection c );
在 ArrayList 的末尾添加 ICollection 的元素。

3、public virtual void Clear();
从 ArrayList 中移除所有的元素。

4、public virtual bool Contains( object item );
判断某个元素是否在 ArrayList 中。

5、public virtual int IndexOf(object);
返回某个值在 ArrayList 中第一次出现的索引,索引从零开始。

6、public virtual void Insert( int index, object value );
在 ArrayList 的指定索引处,插入一个元素。

7、public virtual void InsertRange( int index, ICollection c );
在 ArrayList 的指定索引处,插入某个集合的元素。

8、public virtual void Remove( object obj );
从 ArrayList 中移除第一次出现的指定对象。

9、public virtual void RemoveAt( int index );
移除 ArrayList 的指定索引处的元素。

10、public virtual void RemoveRange( int index, int count );
从 ArrayList 中移除某个范围的元素。

11、public virtual void Reverse();
逆转 ArrayList 中元素的顺序。

12、public virtual void SetRange( int index, ICollection c );
复制某个集合的元素到 ArrayList 中某个范围的元素上。

13、public virtual void Sort();
对 ArrayList 中的元素进行排序。

14、public virtual void TrimToSize();
设置容量为 ArrayList 中元素的实际个数。

eg:
using System;
using System.Collections;

namespace CollectionApplication
{
class Program
{
static void Main(string[] args)
{
ArrayList al = new ArrayList();

        Console.WriteLine("Adding some numbers:");
        al.Add(45);
        al.Add(78);
        al.Add(33);
        al.Add(56);
        al.Add(12);
        al.Add(23);
        al.Add(9);
       
        Console.WriteLine("Capacity: {0} ", al.Capacity);   //结果:  Capacity: 8
        Console.WriteLine("Count: {0}", al.Count);    //结果: Count: 7
                 
        Console.Write("Content: ");
        foreach (int i in al)
        {
            Console.Write(i + " ");     //结果:Content : 45 78 33 56 12 23 9
        }
        Console.WriteLine();
        Console.Write("Sorted Content: ");
        al.Sort();
        foreach (int i in al)
        {
            Console.Write(i + " ");    //结果: Content: 9 12 23 33 45 56 78
        }
        Console.WriteLine();
        Console.ReadKey();
    }
}

}

C#里面Collection下面Queue(队列)

队列(Queue)代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。
当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。

下表列出了 Queue 类的一些常用的 属性:

属性 描述
Count 获取 Queue 中包含的元素个数。

Queue 类的一些常用的 方法:
1 public virtual void Clear();
从 Queue 中移除所有的元素。

2 public virtual bool Contains( object obj );
判断某个元素是否在 Queue 中。

3 public virtual object Dequeue();
移除并返回在 Queue 的开头的对象。

4 public virtual void Enqueue( object obj );
向 Queue 的末尾添加一个对象。

5 public virtual object[] ToArray();
复制 Queue 到一个新的数组中。

6 public virtual void TrimToSize();
设置容量为 Queue 中元素的实际个数。

eg:
using System;
using System.Collections;

namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
Queue q = new Queue();

     q.Enqueue('A');
     q.Enqueue('M');
     q.Enqueue('G');
     q.Enqueue('W');
     
     Console.WriteLine("Current queue: ");
     foreach (char c in q)
        Console.Write(c + " ");
     Console.WriteLine();
     q.Enqueue('V');
     q.Enqueue('H');
     Console.WriteLine("Current queue: ");        
     foreach (char c in q)
        Console.Write(c + " ");
     Console.WriteLine();
     Console.WriteLine("Removing some values ");
     char ch = (char)q.Dequeue();
     Console.WriteLine("The removed value: {0}", ch);
     ch = (char)q.Dequeue();
     Console.WriteLine("The removed value: {0}", ch);
     Console.ReadKey();
  }

}
}

结果:
Current queue:
A M G W
Current queue:
A M G W V H
Removing values
The removed value: A
The removed value: M

C#里面Collection下面SortedList

SortedList 类代表了一系列按照键来排序的键/值对,这些键值对可以通过键和索引来访问。
排序列表是数组和哈希表的组合。它包含一个可使用键或索引访问各项的列表。如果您使用索引访问各项,
则它是一个动态数组(ArrayList),如果您使用键访问各项,则它是一个哈希表(Hashtable)。集合中的
各项总是按键值排序。

下表列出了 SortedList 类的一些常用的 属性:

属性 描述
Capacity 获取或设置 SortedList 的容量。
Count 获取 SortedList 中的元素个数。
IsFixedSize 获取一个值,表示 SortedList 是否具有固定大小。
IsReadOnly 获取一个值,表示 SortedList 是否只读。
Item 获取或设置与 SortedList 中指定的键相关的值。
Keys 获取 SortedList 中的键。
Values 获取 SortedList 中的值。

1 public virtual void Add( object key, object value );
向 SortedList 添加一个带有指定的键和值的元素。

2 public virtual void Clear();
从 SortedList 中移除所有的元素。

3 public virtual bool ContainsKey( object key );
判断 SortedList 是否包含指定的键。

4 public virtual bool ContainsValue( object value );
判断 SortedList 是否包含指定的值。

5 public virtual object GetByIndex( int index );
获取 SortedList 的指定索引处的值。

6 public virtual object GetKey( int index );
获取 SortedList 的指定索引处的键。

7 public virtual IList GetKeyList();
获取 SortedList 中的键。

8 public virtual IList GetValueList();
获取 SortedList 中的值。

9 public virtual int IndexOfKey( object key );
返回 SortedList 中的指定键的索引,索引从零开始。

10 public virtual int IndexOfValue( object value );
返回 SortedList 中的指定值第一次出现的索引,索引从零开始。

11 public virtual void Remove( object key );
从 SortedList 中移除带有指定的键的元素。

12 public virtual void RemoveAt( int index );
移除 SortedList 的指定索引处的元素。

13 public virtual void TrimToSize();
设置容量为 SortedList 中元素的实际个数。

eg:
using System;
using System.Collections;

namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
SortedList sl = new SortedList();

     sl.Add("001", "Zara Ali");
     sl.Add("002", "Abida Rehman");
     sl.Add("003", "Joe Holzner");
     sl.Add("004", "Mausam Benazir Nur");
     sl.Add("005", "M. Amlan");
     sl.Add("006", "M. Arif");
     sl.Add("007", "Ritesh Saikia");

     if (sl.ContainsValue("Nuha Ali"))
     {
        Console.WriteLine("This student name is already in the list");   
     }
     else
     {
        sl.Add("008", "Nuha Ali");
     }

     // 获取键的集合
     ICollection key = sl.Keys;

     foreach (string k in key)
     {
        Console.WriteLine(k + ": " + sl[k]);
     }
  }

}
}
//注意,SortList会根据里面key值进行升序排序

结果:001: Zara Ali
002: Abida Rehman
003: Joe Holzner
004: Mausam Banazir Nur
005: M. Amlan
006: M. Arif
007: Ritesh Saikia
008: Nuha Ali

C#里面Collection下面Stack(栈)

堆栈(Stack)代表了一个后进先出的对象集合。当您需要对各项进行后进先出的访问时,则使用堆栈。
当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。

下表列出了 Stack 类的一些常用的 属性:

属性 描述
Count 获取 Stack 中包含的元素个数。

下表列出了 Stack 类的一些常用的 方法:

序号 方法名 & 描述
1 public virtual void Clear();
从 Stack 中移除所有的元素。

2 public virtual bool Contains( object obj );
判断某个元素是否在 Stack 中。

3 public virtual object Peek();
返回在 Stack 的顶部的对象,但不移除它。

4 public virtual object Pop();
移除并返回在 Stack 的顶部的对象。

5 public virtual void Push( object obj );
向 Stack 的顶部添加一个对象。

6 public virtual object[] ToArray();
复制 Stack 到一个新的数组中。

eg:

using System;
using System.Collections;

namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
Stack st = new Stack();

        st.Push('A');
        st.Push('M');
        st.Push('G');
        st.Push('W');
       
        Console.WriteLine("Current stack: ");
        foreach (char c in st)
        {
            Console.Write(c + " ");
        }
        Console.WriteLine();
       
        st.Push('V');
        st.Push('H');
        Console.WriteLine("The next poppable value in stack: {0}",
        st.Peek());
        Console.WriteLine("Current stack: ");          
        foreach (char c in st)
        {
           Console.Write(c + " ");
        }
        Console.WriteLine();

        Console.WriteLine("Removing values ");
        st.Pop();
        st.Pop();
        st.Pop();
       
        Console.WriteLine("Current stack: ");
        foreach (char c in st)
        {
           Console.Write(c + " ");
        }
    }
}

}

结果:
Current stack:
W G M A
The next poppable value in stack: H
Current stack:
H V W G M A
Removing values
Current stack:
G M A

C#里面继承、接口、多态

C#里面接口、继承、多态

接口使用的注意事项:
1、接口方法不能用public abstract等修饰。接口内不能有字段变量,构造函数。
2、接口内可以定义属性(有get和set的方法)。如string color { get ; set ; }这种。
3、实现接口时,必须和接口的格式一致。
4、必须实现接口的所有方法。
5、接口中只能包含方法、属性、索引器和事件的声明。不允许声明成员上的修饰符,即使是pubilc都不行,
因为接口成员总是公有的,也不能声明为虚拟和静态的。如果需要修饰符,最好让实现类来声明。、
6、接口也可以彼此继承,就象类的继承一样。但是如果一个接口继承上一个接口的话,一样要继承上一个接口所有方法。
7、C#中的接口是独立于类来定义的。这与 C++模型是对立的,在 C++中接口实际上就是抽象基类。
8、接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,
而你只能可以从仅有的一个类派生。
9、一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,
但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。

C#里面接口隔离

什么是接口隔离原理

根据一组方法,最好使用许多小接口来代替一个胖接口,每个小接口服务一个子模块

简单点说,客户端需要什么功能,就提供什么接口,对于客户端不需要的接口不应该强行要求其依赖;
类之间的依赖应该建立在最小的接口上面,这里最小的粒度取决于单一职责原则的划分。
自我理解就是将一个大接口的各个方法和属性细分到许多小接口,然后就可以根据实现类的需要选择相应的接口实现,
避免一个被实现接口中太多用不到的方法,还得被实现。

接口隔离之前
示例
public interface IProduct {
int ID { get; set; }
double Weight { get; set; }
int Stock { get; set; }
int Inseam { get; set; }
int WaistSize { get; set; }
}
public class Jeans : IProduct {
public int ID { get; set; }
public double Weight { get; set; }
public int Stock { get; set; }
public int Inseam { get; set; }
public int WaistSize { get; set; }
}
public class BaseballCap : IProduct {
public int ID { get; set; }
public double Weight { get; set; }
public int Stock { get; set; }
public int Inseam { get; set; }
public int WaistSize { get; set; }
public int HatSize { get; set; }
}


接口隔离后
示例
public interface IProduct {
int ID { get; set; }
double Weight { get; set; }
int Stock { get; set; }
}
public interface IPants {
int Inseam { get; set; }
int WaistSize { get; set; }
}
public interface IHat {
int HatSize { get; set; }
}
public class Jeans : IProduct, IPants {
public int ID { get; set; }
public double Weight { get; set; }
public int Stock { get; set; }
public int Inseam { get; set; }
public int WaistSize { get; set; }
}
public class BaseballCap : IProduct, IHat {
public int ID { get; set; }
public double Weight { get; set; }
public int Stock { get; set; }
public int HatSize { get; set; }
}

C#里面文件流

C#获得桌面绝对路径

可以使用Environment.SpecialFolder来获取当前用户的桌面路径
string desktopPath =Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
System.Environment类提供有关当前环境和平台的信息。
eg:
public static void Main(){
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //如果要访问桌面文件加上+@"\文件名.txt";
Console.WriteLine($"Desktop Path: {desktopPath}");
Console.ReadLine();
}

上面代码的输出是:
Desktop Path: C:\Users\UserName\Desktop

C#里面string类里面常用方法

1.ToArray() (ToCharArray())
ToCharArray (int startIndex, int length);
参数
startIndex
此实例内子字符串的起始位置。
length
此实例内子字符串的长度。

ToCharArray()用于将字符串变为字符数组。
eg: char[ ] arr=str.ToCharArray( );

2.Contains()
Contains (string value);
参数
value
要搜寻的字符串。
可判断字符中是否出现在字符串中,返回bool型
eg:
string name = "raoguang is a chinese!";
string k = "";
char[] chars = name.ToArray();
foreach (char a in chars)
{
if (!(k.Contains(a)))
{
k = k + a;
}
}
Console.WriteLine(k.ToString());
Console.ReadKey();

返回结果:raogun ische!

3.Insert()
Insert (int startIndex, string value);
参数
startIndex
插入的从零开始的索引位置。
value
要插入的字符串。
返回String 类型数据
eg:
string exam = "raoguang is a chinese!";
string example = exam.Insert(8," and his family ");
Console.WriteLine(example);
Console.ReadKey();
返回结果:raoguang and his family is a chinese!

4.ToLower() ----(转化字符串为小写) ToUpper() ----(转化字符串为大写)
eg:
string a=“How are you”;
a=a.ToUpper(); //a=“HOW ARE YOU”;

5.IndexOf()
String.IndexOf 方法 (value, [startIndex], [count])
报告指定字符在此实例中的第一个匹配项的索引。搜索从指定字符位置开始,并检查指定数量的字符位置。
参数含义:
   value
  要查找的 Unicode 字符。 对 value 的搜索区分大小写。
   startIndex(Int32)
  可选项,搜索起始位置。不设置则从0开始。
   count(Int32)
  可选项,要检查的字符位数。
  返回值
  如果找到该字符,则为 value 的索引位置;否则如果未找到,则为 -1。
eg:
string exam = "raoguang is a chinese!";
int position = exam.IndexOf("c");
Console.WriteLine(position);
Console.ReadKey();
返回结果:14

6.Substring()
截断字符串
eg:
string exam = "raoguang is a chinese!";
string a = exam.Substring(3);
string b = exam.Substring(3,5);
Console.WriteLine(a);
Console.WriteLine(b);
Console.ReadKey();

返回结果:
guang is a chinese!
guang

7.Trim()
string strEscape = “\r;\n”;
strSrc = strSrc.Trim(strEscape.ToCharArray());
删除字符串头部和尾部的回车符。

C#中Trim()、TrimStart()、TrimEnd()的用法:
这三个方法用于删除字符串头尾出现的某些字符。
Trim()删除字符串头部及尾部出现的空格,删除的过程为从外到内,直到碰到一个非空格的字符为止,所以不管前后有多少个连续的空格都会被删除掉。
TrimStart()只删除字符串的头部的空格。
TrimEnd()只删除字符串尾部的空格。

如果这三个函数带上字符型数组的参数,则是删除字符型数组中出现的任意字符。
如Trim(“abcd”.ToCharArray())就是删除字符串头部及尾部出现的a或b或c或d字符,删除的过程直到碰到一个既不是a也不是b也不是c也不是d的字符才结束。
这里最容易引起的误会就是以为删除的是"abcd"字符串。
如下例:
string s = " from dual union all ";
s = s.Trim().TrimEnd(“union all”.ToCharArray());
ps:ToCharArray()是将字符串复制为字符数组
可能有人以为上面s的最终结果是"from dual",
但真正的结果是"from d"。
需要注意的是这种写法执行的删除对象是字符数组中出现的任意字符,而不是这些字符连在一起组成的字符串!

eg:
string exam = " raoguang is a chinese ";
string a = exam.Trim();
Console.WriteLine(a);
string b = exam.TrimStart();
Console.WriteLine(b);
string c = exam.TrimEnd();
Console.WriteLine(c);
string d = exam.Trim().TrimEnd("chinese".ToCharArray());
Console.WriteLine(d);
string e = exam.Trim().TrimStart("chinese".ToCharArray());
Console.WriteLine(e);
string f = exam.Trim("chinese".ToCharArray());
Console.WriteLine(f);
返回结果:
raoguang is a chinese
raoguang is a chinese
raoguang is a chinese
raoguang is a
raoguang is a chinese
raoguang is a chinese

8.Split()
将字符串划分为字符串数组
eg:
string exam = "how are you";
string[] a = exam.Split(" ");
foreach (string b in a)
{
Console.WriteLine(b);
}
返回结果:
how
are
you

9.Replace()
Replace(Char, Char)
返回一个新字符串,其中此实例中出现的所有指定 Unicode 字符都替换为另一个指定的 Unicode 字符。
Replace(String, String)
返回一个新字符串,其中当前实例中出现的所有指定字符串都替换为另一个指定的字符串。
eg:
string exam = "how are you";
string a = exam.Replace(" ","|");
Console.WriteLine(a);
string b = exam.Replace("are","do");
Console.WriteLine(b);
返回结果:
how|are|you
how do you

10、String.Join 方法 (String, String[])
在指定 String 数组的每个元素之间串联指定的分隔符 String,从而产生单个串联的字符串。

eg:
string[] a = {"we are one","and you","what's your mean?"};
string b = string.Join("-",a);
Console.WriteLine(b);
返回结果:
we are one-and you-what's your mean?

11、public bool StartsWith( string value )
判断字符串实例的开头是否匹配指定的字符串。
eg:
string a = "abc*d";
bool flag=a.StartsWith("a
"); //return true
bool flag=a.StartsWith("a
b") //return false

12、public bool EndsWith( string value )
判断 string 对象的结尾是否匹配指定的字符串。
eg:
string a = "abcd";
bool flag=a.StartsWith("
d"); //return true
bool flag=a.StartsWith("a*b") //return false

13、String.IsNullOrEmpty()方法
String.IsNullOrEmpty()方法是String类的内置方法,用于检查字符串是Null还是Empty
eg:
string str1="";
string str2=null;
string str3=" ";
string str4="1112";

bool flag=string.IsNullOrEmpty(str1); //true
bool flag=string.IsNullOrEmpty(str2); //true
bool flag=string.IsNullOrEmpty(str3); //false
bool flag=string.IsNullOrEmpty(str4); //false

C#里面反射

反射:用来操作元数据(metadata)的一个类库。(可以把反射当成一个小工具来读取或者操作元数据)

为什么要通过反射间接操作?
1、因为我们需要动态。
2、读取私有对象。

哪些地方用到了反射?
asp.net MVC 、ORM、LOC、AOP几乎所有的裤架都会使用反射

C#里面@符号和$符号的作用

(1)@字符的作用
C#字符串中不能使用没有经过转义的反斜杠字符 " \ ",而需要两个反斜杠字符来表示它:
string filePath=" C:\ProCSharp\First.cs ";
但这种方式容易令人产生疑惑,因此C#提供了替代方式。即可以在字符串字面量的前面加上字符@,在这个字符后的所有字符都看成其原来的含义。
string filePath=@" C:\ProCSharp\First.cs "
(2)字符的作用 对字符串加上前缀,就允许把花括号放在包含一个变量甚或代码表达式的字符串中。变量或代码表达式的结果放在字符串中花括号所在的位置:

C#里面Debug和Release模式区别

release和debug是不同的运行方式:
debug会增加调试代码,方便调试。调试完后,用release版本发布,没有调试代码,减小程序体积,
加快执行速度!

C#里面字典和Hashtable

Dictionary

Dictionary:
必须包含名空间System.Collection.Generic
Dictionary里面的每一个元素都是一个键值对(由二个元素组成:键和值)
键必须是唯一的,而值不需要唯一的
键和值都可以是任何类型(比如:string, int, 自定义类型,等等)
通过一个键读取一个值的时间是接近O(1)
键值对之间的偏序可以不定义

使用方法:

//定义
Dictionary<string, string> openWith = new Dictionary<string, string>();

//添加元素
openWith.Add("txt", "notepad.exe");
openWith.Add("bmp", "paint.exe");
openWith.Add("dib", "paint.exe");
openWith.Add("rtf", "wordpad.exe");

//取值
Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);

//更改值
 openWith["rtf"] = "winword.exe";
 Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);

 //遍历key
  foreach (string key in openWith.Keys)
  {
        Console.WriteLine("Key = {0}", key);   //获得key(键的值)
        
   }

   //遍历value ,方法一
   foreach (string value in openWith.Values)   
   {
       Console.WriteLine("value = {0}", value);  
    }
     //方法二
    foreach (string key in openWith.Keys)
    {
        Console.WriteLine("Values={0}",openWith[key]);  //获得key(键)的values(值)
    }

    //删除元素
    openWith.Remove("doc");
    if (!openWith.ContainsKey("doc"))
    {
         Console.WriteLine("Key \"doc\" is not found.");
     }

     //判断键存在
    if (openWith.ContainsKey("bmp")) // True 
    {
          Console.WriteLine("An element with Key = \"bmp\" exists.");
     }

常用属性
名称 说明
Comparer 获取用于确定字典中的键是否相等的 IEqualityComparer<T>。
Count 获取包含在 Dictionary<TKey, TValue> 中的键/值对的数目。
Item 获取或设置与指定的键相关联的值。
Keys 获取包含 Dictionary<TKey, TValue> 中的键的集合。
Values 获取包含 Dictionary<TKey, TValue> 中的值的集合。

常用方法
名称 说明
Add 将指定的键和值添加到字典中。
Clear 从 Dictionary<TKey, TValue> 中移除所有的键和值。
ContainsKey 确定 Dictionary<TKey, TValue> 是否包含指定的键。
ContainsValue 确定 Dictionary<TKey, TValue> 是否包含特定值。
Equals(Object) 确定指定的 Object 是否等于当前的 Object。 (继承自 Object。)
GetType 获取当前实例的 Type。 (继承自 Object。)
Remove 从 Dictionary<TKey, TValue> 中移除所指定的键的值。
ToString 返回表示当前对象的字符串。 (继承自 Object。)
TryGetValue 获取与指定的键相关联的值。

Hashtable

  1. 哈希表(HashTable)简述
    在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似
    keyvalue的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。
    Hashtable中keyvalue键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对.

  2. 什么情况下使用哈希表
    (1)某些数据会被高频率查询
    (2)数据量大
    (3)查询字段包含字符串类型
    (4)数据类型不唯一

using System;
using System.Collections; //file使用Hashtable时,必须引入这个命名空间
class Program
{
public static void Main()
{
Hashtable ht = new Hashtable(); //创建一个Hashtable实例
ht.Add("北京", "帝都"); //添加keyvalue键值对
ht.Add("上海", "魔都");
ht.Add("广州", "省会");
ht.Add("深圳", "特区");

 string capital = (string)ht["北京"];
 Console.WriteLine(capital)  //打印key="北京"的values值 结果:帝都
 Console.WriteLine(ht.Contains("上海")); //判断哈希表是否包含特定键,其返回值为true或false
 ht.Remove("深圳"); //移除一个keyvalue键值对

 //遍历values
foreach (string value in ht.Values)
{
        Console.WriteLine(value);
}

 ht.Clear(); //移除所有元素

}
}

Dictionary和Hashtable区别

HashTable和Dictionary的区别:
(1).HashTable不支持泛型,而Dictionary支持泛型。
(2). Hashtable 的元素属于 Object 类型,所以在存储或检索值类型时通常发生装箱和拆箱的操作,所以你可能
需要进行一些类型转换的操作,而且对于int,float这些值类型还需要进行装箱等操作,非常耗时。
(3).单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分。多线程程序中推荐使用
Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以
获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减。
(4)在通过代码测试的时候发现key是整数型Dictionary的效率比Hashtable快,如果key是字符串型,Dictionary
的效率没有Hashtable快。

C#里面set和get访问器

属性的访问器包含与获取(读取或计算)或设置(写)属性有关的可执行语句。访问器声明可以包含 get 访问器或 set 访问器,
或者两者均包含。

get {}:get 访问器体与方法体相似。它必须返回属性类型的值。执行 get 访问器相当于读取字段的值。
private string name; // the name field
public string Name // the Name property
{
get
{
return name;
}
}

set {}:set 访问器与返回 void 的方法类似。它使用称为 value 的隐式参数,此参数的类型是属性的类型。
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}

只带有 get 访问器的属性称为只读属性。无法对只读属性赋值。
只带有 set 访问器的属性称为只写属性。只写属性除作为赋值的目标外,无法对其进行引用。
同时带有 get 和 set 访问器的属性为读写属性。
在属性声明中,get 和 set 访问器都必须在属性体的内部声明。

注意:使用get访问器更改对象的状态是一种错误的编程方式,尽量不要在get访问器中更改对象的状态。
eg:
public int Number
{
get
{
return number++; // Don't do this
}
}

使用属性方式访问属性:
使用这种方式需要注意,同一属性的get和set方法不能够分开定义。及name属性的set和get方法都要放在
public string Name的属性定义中,若有两个public string Name编译会报错。编译器会认为Student类定
义了两个同名的属性,一个只读一个只写。

eg:
class Student
{
private string name;
private int number;
public string Name
{
set
{
name = value;
}
get
{
return name;
}
}
public int Number
{
set
{
number = value;
}
get
{
return number;
}
}
}

set和get访问器的好处:1、读取设置分开,这样代码便于维护,当访问器中的某个字段需要添加新的判断条件时候,
只需要在访问器中添加判断语句或者做条件修改,而无需给程序中所有该字段添加判断和条件语句。

C#里面泛型

List<object> objlist=new List<object>() {}; object类型做数据转换时候有拆装箱操作,有性能损耗,建议少用。

泛型约束:定义泛型时,可以对泛型类或泛型接口,方法能够接收的类型参数的种类加以限制。在编译阶段,
如果使用不符合要求的类作为类型参数,则会产生编译错误。

六种约束的格式说明
where T:struct
class Stack<TElement> where TElement :struct
限制类型参数必须是值类型,并且不可以是可空值类型(例如int?,char?,double?,bool?等)

where T: class
class Stack<TElement> where TElement :class
限制类型参数必须是引用类型

where T:基类名
class Stack<TElement> where TElement :BaseClass
限制类型参数必须是继承自指定的基类,或是基类本身

where T:接口名
class Stack<TElement> where TElement :IInterface
限制类型参数必须是实现指定接口,或是指定接口

where T:new()
class Stack<TElement> where TElement :new()
限制类型参数必须具有无参构造函数
对new()解释说到是where字句的构造函数约束,带有new()约束的任何类型都必须有可访问的无参构造函数,
正常来说C#创建的类默认都有一个无参的构造函数,即使你没有写,但是如果你写了一个有参数的构造函数后,
那么就没有默认无参的那个了,就需要自己手动写一个。
其实说的很明白,就是where字句后面有new()约束的话,该类中必须有公有的无参的构造函数。
当出现这种情况时候:
public static void show<T>(T t)where T:new() //这个约束表示T类型只接受带一个无参构造函数的类型对象

C#里面强类型和弱类型

强类型和弱类型的变量都有两个属性:类型和值。

强类型的变量类型是不能改变的,弱类型的变量类型是随需改变的,这是强弱的真正含义。

#C#里面

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容