细碎的.net

本文深入探讨了C#中的关键概念,包括线程模型STA与MTA的区别、throw与throwex的使用区别、IEnumerable与IEnumerator的不同遍历方式、yield return的运用以及==与equal()方法的区别等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程单元的含义

  • 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 字段可用于运行时常数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值