线程单元的含义
- STA的程序每个线程都有自己独立的资源,别的线程访问不到
- MTA则是.NET程序的默认线程模型 , 就是n个线程可以共用一个资源
STAThread 属性或InvokeThread.SetApartmentState(ApartmentState.STA); 可以防止调用com组件出错。
throw和throw ex的区别
在使用异常捕获语句try…catch…throw语句时,在C#中推荐使用throw;来抛出异常;throw ex;会将到现在为止的所有信息清空,认为你catch到的异常已经被处理了,只不过处理过程中又抛出新的异常,从而找不到真正的错误源。
参考
IEnumerable 和 IEnumerator
- 遍历方法不一样
- IEnumerator 可以记录遍历的位置,而IEnumerable 不行
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
public class IEnumerableAndIEnumerator
{
private List<int> list = new List<int>();
public void Analyze()
{
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
IEnumerable<int> enumerable = (IEnumerable<int>)list;
Console.WriteLine("Loop IEnumerable-------------");
IterateLess2(enumerable);
IEnumerator<int> enumerator = list.GetEnumerator();
Console.WriteLine("Loop IEnumerator-------------");
IterateLess2(enumerator);
}
private void IterateLess2(IEnumerator<int> items)
{
while (items.MoveNext())
{
Console.WriteLine(items.Current);
if (items.Current > 2)
{
IterateAbrove2(items);
}
}
}
private void IterateAbrove2(IEnumerator<int> items)
{
while (items.MoveNext())
{
Console.WriteLine(items.Current);
}
}
private void IterateLess2(IEnumerable<int> items)
{
foreach (int item in items)
{
Console.WriteLine(item);
if (item > 2)
{
IterateAbrove2(items);
}
}
}
private void IterateAbrove2(IEnumerable<int> items)
{
foreach (int item in items)
{
Console.WriteLine(item);
}
}
}
}
运行结果如图
yield return
使用yield return为什么能保证每次循环遍历的时候从前一次停止的地方开始执行,当希望获取一个IEnumerable类型的集合,而不想把数据一次性加载到内存,就可以考虑使用yield return实现”按需供给”.
C#通过yield实现数组全排列的方法
static void Main(string[] args)
{
foreach (var i in Perm(new int[] { 3, 6, 9}, 0))
{
string s = string.Join(",", i.Select(j => j.ToString()).ToArray());
}
Console.Read();
}
static void Swap<T>(ref T a, ref T b)
{
T t = a;
a = b;
b = t;
}
static IEnumerable<int[]> Perm(int[] arr, int pos)
{
if (pos == arr.Length)
{
yield return arr;
}
for (int i = pos; i < arr.Length; ++i)
{
Swap(ref arr[i], ref arr[pos]);
foreach (var j in Perm(arr, pos + 1)) yield return j;
Swap(ref arr[i], ref arr[pos]);
}
}
== 和.equal()
- == 比较的是对象的应用
- equal 比较的是对象的内容
- string 总是比较内容
Object s1 = "Hello World";
Object s2 = new string("Hello World".ToCharArray());
Console.WriteLine(s1==s2);
Console.WriteLine(s1.Equals(s2));
输出结果:
false
true
MDI窗体(多文档界面)
多文档界面程序是允许创建在单个容器中包含多个窗体的应用程序,只需将该窗体的IsMdiContainer属性设置为True即可。MDI应用,最典型的应用就是,子窗体在父窗体中停靠。
readonly 、const
readonly 关键字与 const 关键字不同。 const 字段只能在该字段的声明中初始化。 readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。另外,const 字段为编译时常数,而 readonly 字段可用于运行时常数