[深入学习C#]LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询

此文章非原创,转载自诗人江湖老,原文地址

  在Git上下载源码
  在工程中我们少不了要定义类或者结构去储存数据,这些数据将被临时地储存在内存中,现在我们想要对其完成一些类似于查找、过滤等等常见的任务的时候,我们该如何去做呢?
  我们可以自己写代码去对集合中的每个对象进行遍历,检查变量的每个字段看其是否满足条件。这样的故事已经发生太多次了,微软怎么可能容忍在C#里发生如此弱智的事情呢?于是,C#的设计者决定在C#中集成查询的语法,以最大限度地减少程序员书写类似代码的情况。
  这也就是我们说的LINQ(Language Intergated Query)也就是语言集成查询,我们可以使用同样的语法访问不同的数据源。

为什么要使用LINQ?

  几乎所有的应用程序都需要对数据进行处理,大部分的程序都通过自定义的逻辑来完成这些操作。这样做的弊端之意就是,代码逻辑将会跟它处理的数据的结构紧密耦合在一起,如果数据结构发生了改变,也许将会带来海量的代码改动。
  为了解决这个问题,C#将这些处理数据的代码都抽象出来,提供给了广大开发者。这就是LINQ。
  LINQ的语法类似于关系和分层查询语言(SQL和XQuery),我们可以在不更改查询代码的情况下对数据结构进行更改。LINQ比之SQL要更加灵活,可以处理更广泛的逻辑数据结构。当然,这些数据结构都需要实现了IEnumerable或者IEnumerable< T >接口,才可以进行LINQ查询。

LINQ查询表达式语法详解

表达式基础语法

  LINQ查询表达式以from子句开始,以select或者group子句结束。在这两个子句之间可以跟零个或者多个from、let、where、join或者orderby子句。
  每个from子句都是一个生成器,该生成器将引入一个包括序列(Sequence)的元素的范围变量(range variable)。每个let子句都会引入一个范围变量,以表示通过前一个范围变量计算的值。每个where子句都是一个筛选器,用于从结果中排除项。每个join子句都将指定的源序列键与其他序列的键进行比较,以产生匹配对。每个orderby子句都会根据指定的条件对各项进行重新排序。而最后的select或者group子句根据范围变量来指定结果的表现形式。最后可以使用into子句来连接查询,将某一查询结果的视为后续查询的生成器。

标准查询操作符

  在了解LINQ查询表达式之前,怎么能不了解下它的查询操作符呢?下面列表列出了LINQ定义的标准查询操作符。

表1:LINQ标准查询操作符

标准查询操作符说明
where OfType<TResult>筛选操作符定义了返回元素的条件。在Where查询操作符中,可以使用谓词,例如Lambda表达式定义的谓词,来返回布尔值。OfType<TResult>根据类型筛选元素,只返回TResult的类型元素
Select 和SelectMany投射操作符用于把对象转换为另一个类型的新对象。Select和SelectMany定义了根据选择器函数选择结果值的投射。
OrderBy、ThenBy 、OrderByDescending 、ThenByDescending 、Reverse排序操作符改变所返回的元素的顺序。OrderBy按升序排列,OrderByDescending按降序排列。如果第一次排序结果很类似,就可以使用ThenBy和ThenByDescending操作符进行第二次排序。Reverse反转集合中的元素顺序。
GroupBy、ToLookUp组合运算符把数据放在组里面。GroupBy操作符组合有公共键的元素。ToLookUp通过创建一个一对多的字典,来组合元素。
Join、GroupJoin链接运算符用于合并不直接相关的集合。使用Join操作符,可以根绝键选择器函数连接两个集合,这类似于SQL中的Join。GroupJoin操作符连接两个集合,组合其结果。
Any、All、Contains如果元素序列满足指定的条件,两次操作符就返回布尔值。Any、ALll和Contains都是限定符操作符。Any确定集合中是否有确定满足谓词函数的元素。ALll确定集合中的所有元素是否都满足谓词函数。Contains检查某个元素是否在集合中。这些操作符都返回一个布尔值。
Take、Skip、TakeWhile、SkipWhile分区操作符返回集合的一个子集,Take、Skip、TakeWhile、SkipWhile都是分区操作符。使用它们可以得到部分结果,使用Take必须指定要从集合中提取的元素个数;Skip跳过指定个数的元素,提取其它元素;TakeWhile提取条件为真的元素。
Distinct、Union、Intersect、Except、ZipSet操作符返回一个集合。Distinct从集合中删除重复的元素,除了Distinct之外,其它的Set操作符都需要两个集合。Union返回出现在其中一个集合中的唯一元素。Intersect返回两个集合中都有的元素。Except返回值出现在一个集合中的元素。Zip是.NET 4新增的,它把两个集合合并为一个。
First、FirstOrDefault、Last、LastOrDefault、ElementAt、ElementAtOrDefault、Single、SingleOrDefault这些元素操作符仅返回一个元素。First返回第一个满足条件的元素。FirstOrDefault类似于First,单如果没有找到满足条件的元素,就返回类型的默认值。Last返回最后一个满足条件的元素。ElementAt指定了要返回的元素的位置。Single只返回一个满足条件的元素。如果有多个元素都满足条件,就抛出一个异常。
Count、Sum、Min、Max、Average、Aggregate聚合操作符计算集合的一个值。利用这些聚合操作符,可以计算所有值的总和、所有元素的个数、值最大和最小的元素,以及平均值等等。
ToArray、ToEnumerable、ToList、ToDictionary、Cast<TRsult>这些转换操作符将集合转换为数组:IEnumerable、IList、IDictionary等。
Empty、Range、Repeat这些生成操作符返回一个心机和。使用Empty时集合是空的;Range返回一系列数字;Repeat返回一个始终重复一个值的集合。

设置案例背景

  假设我们有4个类,Customer,Order,Detail,Product,它们的定义如下:

Customer类字段字段类型
CustomerIDint
Countrystring
Namestring
Citystring
OrdersList<Order>
Order类字段字段类型
OrderIDint
CustomerIDint
Totalint
OrderDateDateTime
DetailsList<Detail>
Detail类字段字段类型
DetailIDint
OrderIDint
UnitPricedouble
Quantitydouble
ProductIDint
Product类字段字段类型
ProductIDint
ProductNamestring

  假设现在它们各自有一个List集合,分别为Customers,Orders,Details,Products。我们在这基础之上来一步步阐述LINQ查询表达式。
  customers数据:

CustomerIDCityCountryNameOrders
0北京中国小米orders.FindAll(c => c.CustomerID == 0)
1首尔韩国三星orders.FindAll(c => c.CustomerID == 1)
2加州美国苹果orders.FindAll(c => c.CustomerID == 2)
3台北中国HTCorders.FindAll(c => c.CustomerID == 3)
4珠海中国魅族orders.FindAll(c => c.CustomerID == 4)
5北京中国华为orders.FindAll(c => c.CustomerID == 5)
6上海中国索尼orders.FindAll(c => c.CustomerID == 6)
7北京中国联想orders.FindAll(c => c.CustomerID == 7)
8上海中国诺基亚orders.FindAll(c => c.CustomerID == 8)

  
  orders数据:

OrderIDCustomerIDOrderDateDetails
00DateTime.Nowdetails.FindAll(d => d.OrderID == 0)
10DateTime.Nowdetails.FindAll(d => d.OrderID == 1)
21DateTime.Nowdetails.FindAll(d => d.OrderID == 2)
31DateTime.Nowdetails.FindAll(d => d.OrderID == 3)
42DateTime.Nowdetails.FindAll(d => d.OrderID == 4)
52DateTime.Nowdetails.FindAll(d => d.OrderID == 5)
63DateTime.Nowdetails.FindAll(d => d.OrderID == 6)
73DateTime.Nowdetails.FindAll(d => d.OrderID == 7)
84DateTime.Nowdetails.FindAll(d => d.OrderID == 8)
95DateTime.Nowdetails.FindAll(d => d.OrderID == 9)
106DateTime.Nowdetails.FindAll(d => d.OrderID == 10)
116DateTime.Nowdetails.FindAll(d => d.OrderID == 11)
127DateTime.Nowdetails.FindAll(d => d.OrderID == 12)
137DateTime.Nowdetails.FindAll(d => d.OrderID == 13)
148DateTime.Nowdetails.FindAll(d => d.OrderID == 14)
158DateTime.Nowdetails.FindAll(d => d.OrderID == 15)
168DateTime.Nowdetails.FindAll(d => d.OrderID == 16)

  
  details数据:

DetailIDOrderIDProductIDQuantityUnitPrice
000100010
11121348
22112369
3307547
442235412
550698513
662421310
773197710
8822876
995977812
1010485411
1111275610
1212310009
131317868
141433467
151525766
1616078210

  
  products数据:

ProductIDProductName
0samsung
1nokia
2apple
3xiaomi
4huawei
5lenovo

Demo查询表达式

条件筛选

  使用where子句,可以按照一个或者多个条件筛选集合,where子句的表达式的结果类型应该是布尔类型。
  筛选在北京且名称以‘小’开头的顾客。

var query = from c in customerswhere c.City == "北京" && c.Name.StartsWith("小")select c;
foreach (Customer item in query)
{Console.WriteLine(item.Name + "\t\t" + item.City);
}
Console.ReadKey();

  该LINQ查询会返回在北京而且名字以“小”开头的Customer集合。
  输出结果:
  这里写图片描述
  

复合from子句筛选

  当需要根绝对象的一个成员进行筛选,而该成员本身是一个集合或者列表,就可以使用复合的from子句。
  筛选订单数量大于800的信息。

var query = from c in customersfrom o in c.Ordersfrom d in o.Detailswhere d.Quantity > 800select new { Name = c.Name, Total = d.UnitPrice * d.Quantity };foreach (var item in query)
{Console.WriteLine(item.Name + "\t\t" + item.Total);
}
Console.ReadKey();

  输出结果:
  这里写图片描述
  

排序

  要对序列排序,需要使用orderby子句。
  按照城市、顾客ID进行排序。 

var query = from c in customersfrom o in c.Ordersorderby c.City, o.CustomerIDselect new { Name = c.Name, City = c.City, OrderID = o.OrderID };foreach (var item in query)
{Console.WriteLine(item.Name + "\t\t" + item.City + "\t\t" + item.OrderID);
}
Console.ReadKey();

  输出结果:
  这里写图片描述
    

分组

  要根木一个关键值对查询结果分组,可以使用group子句。
  统计各个产品的订单数量。  

var query = from d in detailsgroup d by d.ProductID into gorderby g.Count(), g.Keyselect new { Name = g.Key, Count = g.Count() };
Console.WriteLine("ProductID"+ "\t" + "Count");
foreach (var item in query)
{Console.WriteLine(item.Name + "\t\t" + item.Count);
}
Console.ReadKey();

  输出结果:
  这里写图片描述
  

对嵌套的对象分组

  如果分组的对象包含嵌套的序列,则各个改变select子句创建的匿名类型。
  统计各个产品的订单数量,并输出各个订单的订货数量。

var query = from d in detailsgroup d by d.ProductID into gorderby g.Count(), g.Keyselect new{Name = g.Key,Count = g.Count(),Quantity =  from d in gorderby d.Quantityselect d.Quantity};Console.WriteLine("ProductID"+"\t"+"Count"+"\t"+"Quantity");
foreach (var item in query)
{Console.Write(item.Name + "\t\t" + item.Count+"\t");foreach (var quantity in item.Quantity){Console.Write("{0};", quantity);}Console.WriteLine();
}
Console.ReadKey();

  输出结果:
  这里写图片描述
  

连接

  使用join子句可以根据特定的条件合并两个数据源,但之前要获得两个要连接的列表。
  统计各个顾客和其订单的信息。

var query = from r infrom c in customersfrom o in c.Ordersfrom d in o.Detailsselect new { Name = c.Name, City = c.City, Money = d.Quantity * d.UnitPrice, ProductID = d.ProductID }join t infrom p in productsselect pon r.ProductID equals t.ProductIDselect new { Name = r.Name, City = r.City, Money = r.Money, ProductName = t.ProductName };
Console.WriteLine("Name" + "\t" + "City" + "\t" + "Money" + "\t" + "ProductName");
foreach (var item in query)
{Console.WriteLine(item.Name + "\t" + item.City + "\t" + item.Money + "\t" + item.ProductName);
}
Console.ReadKey();

  输出结果:
  这里写图片描述
    

聚合操作符

  聚合操作符(包括Count()、Sum()、Min()、Max()、Average()和Aggregate())它们不返回一个序列,而是返回一个值。
  Count()方法返回集合中的项数;Sum()方法汇总序列中所有数字,返回这些数字的和;Min()方法返回集合中的最小值;Max()方法返回集合中的最大值;Average()方法计算集合中的平均值;Aggregate()方法,可以传递一个Lambda表达式,该表达式对所有的值进行聚合。
  这些方法的使用方式类似,都是直接对序列或者集合进行操作。下面用Sum()做一个示例:
  统计各个顾客总共订单的订货数量。

var query = from r infrom c in customersselect new{Name = c.Name,OrderCount = (  from o in c.Ordersfrom d in o.Detailsselect d.Quantity).Sum()}orderby r.OrderCountselect r;

  输出结果:
  这里写图片描述

使用扩展方法和Lambda表达式简化LINQ查询

什么是扩展方法

  当方法的第一个形参包含this修饰符的时候,该方法称为扩展方法。扩展方法只能在非泛型、非嵌套的静态类中声明,扩展方法的第一个形参不能带有除this之外的其他任何修饰符,而且形参类型不能是指针类型。
  下面的程序是一个扩展方法的示例:

public static class Extensions
{public static void HelloWorld(this string str){Console.WriteLine("{0} 调用了:HellWorld",str);}
}

  现在就可以调用该方法了:

string str="Jay";
str.HelloWorld();

  我们可以看到,控制台中输出了“Jay 调用了:HelloWorld”。
  之所以这样,是因为HelloWorld第一个参数类型为string类型,因此该方法就是string类型的扩展方法,所有的string类型变量都可以调用,而变量的内容就是传递给HelloWorld的参数。
  上面的程序和下面的代码结果一样:

string str = "Jay";
Extensions.HelloWorld(str);

    LINQ扩展方法

      LINQ为IEnumerable<T>接口提供了各种扩展方法,以便用户在实现了该接口的任意集合上使用LINQ查询。表1中列出的LINQ查询操作符,都有相应的扩展方法实现。
      使用扩展方法可以和使用LINQ查询表达式获得十分类似甚至是相同的结果,当扩展方法和Lambda表达式结合的时候,会大大简化LINQ查询。
      

    简化LINQ查询

      前面一节的条件筛选LINQ表达式可以简化为:

    var query = customers.Where(c => c.City == "北京" && c.Name.StartsWith("小")).Select(c => c);
    • 1

      
      前面一节的条件复合from子句筛选LINQ表达式可以简化为:

    var query = customers.SelectMany(c => c.Orders, (c, o) => new { _customer = c, _order = o, _detail = o.Details }).SelectMany(a => a._detail, (a, b) => new { _var = a, Total = b.Quantity * b.UnitPrice, Quantity = b.Quantity }).Where(_nameless => _nameless.Quantity > 800).Select(_annonymous => new { Name = _annonymous._var._customer.Name, Total = _annonymous.Total });
    • 1

      
      前面一节的排序LINQ表达式可以简化为:

    var query = customers.SelectMany(c => c.Orders, (c, o) => new { _customer = c, _order = o }).OrderBy(_var => _var._customer.City).ThenBy(_var => _var._order.CustomerID).Select(_annonymous => new { Name = _annonymous._customer.Name, City = _annonymous._customer.City, OrderID = _annonymous._order.OrderID });
    • 1

      
      前面一节的分组LINQ表达式可以简化为:

    var query = details.GroupBy(d => d.ProductID).OrderBy(g => g.Count()).ThenBy(g => g.Key).Select(g => new { Name = g.Key, Count = g.Count() });
    • 1

      
      前面一节的对嵌套的对象分组LINQ表达式可以简化为:

    var query = details.GroupBy(d => d.ProductID).OrderBy(g => g.Count()).ThenBy(g => g.Key).Select(_var => new { Name = _var.Key, Count = _var.Count(), Quantity = _var.OrderBy(d => d.Quantity).Select(d => d.Quantity) });
    • 1

      前面一节的连接LINQ表达式可以简化为:

    var query = customers.SelectMany(c => c.Orders, (c, o) => new { Name = c.Name, City = c.City, Details = o.Details }).SelectMany(_var => _var.Details, (_var, _detail) => new { Name = _var.Name, City = _var.City, Money = _detail.Quantity * _detail.UnitPrice, ProductID = _detail.ProductID }).Join(products, a => a.ProductID, b => b.ProductID, (a, b) => new { Name = a.Name, City = a.City, Money = a.Money, ProductName = b.ProductName });
    • 1

      
      前面一节的聚合操作LINQ表达式可以简化为:

    var query = customers.Select(c => new { Name = c.Name, OrderCount = c.Orders.SelectMany(o => o.Details, (o, d) => new { _Quantity = d.Quantity }).Select(_var => _var._Quantity).Sum() }).OrderBy(_var => _var.OrderCount);
    • 1

      以上利用扩展方法和Lambda表达式的简化后的LINQ查询代码的查询结果,与LINQ查询表达式结果完全一样,证明这样是完全可行的。
      唯一的问题就是代码看起来比较费解了。

    LINQ查询表达式简化转换原则

      看到这里我们可能要奇怪,为什么我们能用这样的方式来简化LINQ查询表达式呢?
      关于这个问题,我们将在下一篇文章进行详细讲解。
      欢迎大家点击阅读。
      本人还是菜鸟,写的不对的地方还请各位不吝赐教!

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548653.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    hcip第18天

    链路聚合 --- 可以将多个物理接口捆绑成一个逻辑接口&#xff0c;即将N条物理链路聚合为一条逻辑链路。可以在不升级硬件的条件下&#xff0c;达到增加带宽的效果。 我们将逻辑链路&#xff0c;称为聚合链路&#xff0c;在华为设备中称为ETH-TRUNK链路&#xff08;这个技术是针…

    x264编码参数大测试:08 subme与指定码率(1000Kbps)

    一、测试内容 测试方法—— x264编码参数大测试&#xff1a;索引贴 http://www.cnblogs.com/zyl910/archive/2011/12/14/x264_encode_param.html 测试参数—— subme&#xff1a;9、10、11。设定子像素&#xff08;subpixel&#xff09;运动估计&#xff08;motion estimation&…

    [深入学习C#]LINQ查询表达式详解(2)——查询表达式的转换

    转载自诗人江湖老,原文地址 C#在执行LINQ查询表达式的时候&#xff0c;并不会指定其执行语义&#xff0c;而是将查询表达式转换为遵循查询表达式模式的方法的调用。具体而言&#xff0c;查询表达式将转换为以下名称的调用&#xff1a;Where、Select、SelectMany、Join、GroupJo…

    第十八天实验-交换综合

    配置思路 eth-trunk &#xff1e; 创建vlan &#xff1e; 划分vlan &#xff1e; trunk干道 &#xff1e; STP &#xff1e; SVI &#xff1e; VRRP &#xff1e; DHCP 一&#xff0c;配置eth-trunk SW&#xff11;&#xff1a; [sw1]int Eth-Trunk 0 ---创建…

    [深入学习C#]匿名函数、委托和Lambda表达式

    转载自诗人江湖老,原文地址 匿名函数&#xff08;Anonymous Function&#xff09;是表示“内联”方法定义的表达式。匿名函数本身及其内部没有值或者类型&#xff0c;但是可以转换为兼容的委托或者表达式树类型(了解详情)。匿名函数转换的计算取决于转换的目标类型&#xff1a;…

    HCIA第九节课作业

    子网划分&#xff1a; 如何去合理的分配地址 总共需要多少个网段&#xff1f; 14个网段 环回接口8个6个 192.168.1.0/14 借4位 192.168.1.0/28 192.168.1.16/28 192.168.1.32/28 192.168.1.48/28 可用地址数量是多少?14个地址 子网划分第多少位的时候,只有两个可…

    如何下载防盗链的歌曲?

    初音&#xff0c;大家都很熟悉了。它是YAHAMA&#xff08;雅马哈&#xff0c;就是生产电子琴的那个公司&#xff09;推出的音乐编辑软件vocaloid的一款产品。 1月27号&#xff08;春节放假回来的前一天&#xff09;就要推出vocaloid 3啦&#xff01;&#xff01; 很喜欢IA的《鸟…

    SQL Server大量数据秒级插入/新增/删除

    转载自诗人江湖老,原文地址 /// <summary>/// 快速保存数据&#xff0c;自动识别insert和update/// </summary>/// <param name"_sourceTable">需要保存的源数据表</param>/// <param name"_sqlCon">数据库连接</param&g…

    在当前主机添加两块网卡,将两块网卡绑定实现网卡冗余操作。

    编辑虚拟网络接口配置文件,指定网卡IP 1. change the /etc/sysconfig/network-scripts/ifcfg-bond0 configuration. # cat ifcfg-bond0 DEVICEbond0 BOOTPROTOstatic IPADDR172.24.80.168 NETMASK255.255.255.0 BROADCAST172.24.80.250 ONBOOTyes TYPEEthernet # 不…

    如何发布.Net MVC 网站项目(攻略集锦)

    转载自诗人江湖老&#xff0c;原文地址 参考文献既然是攻略&#xff0c;就必然有参考文献&#xff0c;放在文章开头&#xff0c;以示敬意&#xff01; 1.MVC项目发布步骤 2.未能从程序集加载“System.ServiceModel.Activation.HttpModule” 3. Win7 IIS 另一个程序正在使用此…

    ssh建立原理 及配置两台主机的远程连接实现免密登陆

    一、SSH是什么&#xff1f;具体的实现有哪些&#xff1f; SSH是一种协议标准 SSH是用在安全远程登录以及其它安全网络服务 二、SSH原理&#xff1a; SSH为Secure Shell的缩写&#xff0c;默认端口22&#xff0c;由IETF的网络小组&#xff08;Network Working Group&…

    ssh-scan处理手记

    登陆一台Linux RedHat As4的服务器&#xff0c;发现有很多网络连接&#xff0c;为本机去连接其他服务器的22端口。再一看进程&#xff0c;好多ssh-scan的进程。估计是密码设得太简单&#xff0c;被人家黑了。处理思路&#xff1a;找到ssh-scan进程的相应程序文件&#xff0c;删…

    常用 SQL Server 规范集锦

    原文地址 常见的字段类型选择   &#xff11;.字符类型建议采用varchar/nvarchar数据类型   &#xff12;.金额货币建议采用money数据类型   &#xff13;.科学计数建议采用numeric数据类型   &#xff14;.自增长标识建议采用bigint数据类型 (数据量一大&#xff…

    Linux服务器搭建----Web服务器(apache)

    WWW的介绍 万维网&#xff08;亦作“Web”、“WWW”、“W3”&#xff0c;英文全称为“World Wide Web”&#xff09;&#xff0c;是一个由许多互相链接的超文本组成的系统&#xff0c;通过互联网访问。在这个系统中&#xff0c;每个有用的事物&#xff0c;称为一样“资源”&…

    Pa interface issue——PA_EXCEED_ROUND_LIMIT

    最近处理一个PA_TRANSACTION_INTERFACE_ALL的Error Error_code:PA_EXCEED_ROUND_LIMIT 原因是PA_EXCEED_ROUND_LIMIT is null or too small for cost*invoice_rate - cost*actual_rate. 就是说limit的value为空或者不满足金额*当前汇率与金额*录入时汇率的差额。 问题的难点在于…

    C#实现 Linq 序列的Distinct—— IEnumerable.Distinct()——IEqualityComparer

    转载自诗人江湖老&#xff0c;原文地址 在C#中使用List或者Collection的时候&#xff0c;我们经常需要使用到Distinct操作&#xff0c;但是微软默认提供的Distinct重载方法并不能满足我们的需求。这时候&#xff0c;我们就需要自己动手做一番工作了。 Distinct方法的重载 Linq…

    F5 配置手册 -F5 BIG-IP 10.1-1-激活

    F5 配置手册 F5 BIG-IP 10.1-1-激活 统一沟通(中国)有限公司 2012-01-29 前言&#xff1a; F5---太贵! 不过你如果有命运看到这个文章,F5也就不值钱了。 因为:F5提供测试版的虚拟机,我们买不起,总应该玩得起吧! 但愿F5提供更多的机会,给别人机会,也是给自己机会。 参照: 你也可…

    [深入学习C#]利用反射给对象赋值

    转载自诗人江湖老&#xff0c;原文地址  C#中利用反射能够获取对象的属性信息&#xff0c;也可以利用反射给对象赋值。 我们如果想利用凡是给一个对象属性赋值可以通过PropertyInfo.SetValue()方式进行赋值&#xff0c;但要注意值的类型要与属性保持一致。   假设我们有如下…

    快速配置 Samba 将 Linux 目录映射为 Windows 驱动器

    一、局域网内的 Linux 服务器上操作步骤&#xff1a;  1、安装samba&#xff08;CentOS Linux&#xff09;&#xff1a; yum install samba system-config-samba samba-client samba-common2、创建www账号 /usr/sbin/groupadd www/usr/sbin/useradd -g www wwwcat /etc/passw…

    用委托来实现IEqualityComparer接口

    转载自诗人江湖老&#xff0c;原文地址 class FuncEqualityComparer<T> : IEqualityComparer<T> {readonly Func<T, T, bool> _comparer;readonly Func<T, int> _hash;public FuncEqualityComparer( Func<T, T, bool> comparer ): this( compar…