c#

  • dynamic
dynamic o = "a";
dynamic o1 = "a";
o == o1; //true  比较的是字符串的内容而不是引用
  • record 的使用
//record 的使用  
    public record Person(string FirstName, string LastName);
    Person person = new("Nancy", "Davolio");
  • var 和 dynamic
//var 在不好定义类型的情况下使用。
//dynamic 在不知道类型内容的情况下使用。 类是 json的对象。
//存储dynamic 数组,可以进行json序列化
List<dynamic> list = new List<dynamic>(); 
  • linq
from p in list
join emp in db_emp_list on p.UID equals emp.ID
join u in db_user_list on p.DoctorUserID equals u.ID into g
from u in g.DefaultIfEmpty()
select new { id = p.ID, name = emp.Name, dt = p.DT, doctorName = u == null ? "" : u.Name, outStorageUserID = p.OutStorageUserID };
//into g 是 LINQ 查询中的 分组连接(Group Join) 语法的一部分。它的作用是将连接操作的结果存储到一个临时分组变量 g 中。
//将 list 中的每个元素 p 与 db_user_list 中的元素 u 进行连接
//连接条件是 p.DoctorUserID 等于 u.ID
//连接结果不是直接展开,而是先分组放入临时变量 g 中
//from u in g.DefaultIfEmpty() 的作用
//从分组 g 中取出元素 u
//如果分组 g 中没有匹配的元素(即没有找到对应的 u),则使用 DefaultIfEmpty() 提供的默认值(对于引用类型是 null)
//这样就保证了即使右表 (db_user_list) 中没有匹配记录,左表 (list) 的记录仍然会出现在结果中

整个查询相当于 SQL 中的:

SELECT p.ID as id, emp.Name as name, p.DT as dt, 
       ISNULL(u.Name, '') as doctorName, p.OutStorageUserID
FROM list p
INNER JOIN db_emp_list emp ON p.UID = emp.ID
LEFT JOIN db_user_list u ON p.DoctorUserID = u.ID
  • 读取 excel
//读取 excel:
string path = Server.MapPath(System.IO.Path.Combine("Files", saveFileName));
using (var stream = new FileStream(path, FileMode.Open))
      {
          XSSFWorkbook xssWorkbook = new XSSFWorkbook(stream);
          sheet = xssWorkbook.GetSheetAt(0);
    var row = sheet.GetRow(rowNum);
    if (row == null) return string.Empty;
    var cell = row.GetCell(1);
          string v = cell == null ? string.Empty : cell.ToString();
}
  • 匿名类
//匿名类,临时使用的类。
//一般可以用在 后台调用函数返回前台的临时数据结构
//或者需要临时使用数据结构又不想定义类,右键类时js的 obj {a: 1, b: 2}
//例子一: 
return new {a = 1, b = 2};
//例子二:
List<Object> list = new List<Object>();
list.Add(new {a = 1, b = 2});
list.Add(new {a = 2, b = 5});
return list;
  • lock
    • lock的使用
      • 资料
      • 注意⚠️:Lock 锁定的对象,应该是【静态】的【只读】的【引用】类型(字符串除外)。
      //锁变量的定义
      //静态: 防止并发的时候每次new一个类,类中属性锁变量被重新创建。
      //只读: 防止锁变量被修改,从而锁不住
      private static readonly Object Lock1Obj = new Object();
      
      • 如果使用了非static的变量,由于每次锁定的是不同的变量,所以和没有锁定一样。
      //⚠️ 错误示例:
      public partial class test_Lock_1 : System.Web.UI.Page
      {
          private object LockObj = new object(); //⚠️:此处不是static的类型,是错误的。
          protected void Page_Load(object sender, EventArgs e)
          {
              TestLock();
          }
      
          private void TestLock()
          {
              Response.Write("<br>Before lock");
              Response.Flush();
              lock (LockObj)
              {
                  Response.Write("<br>Locking ...");
                  Response.Flush();
                  Thread.Sleep(10000);
              }
              Response.Write("<br>After lock.");
              Response.Flush();
          }
      }
      
      • lock 代码中可以使用return
      //在C#中,lock 是一个表达式,并且它是一个语法糖,它实际上是对 Monitor.Enter 和 Monitor.Exit 的封装。因此,你可以在 lock 块中 return,并且不会有任何问题。
      public class Program
      {
          private static object _lockObject = new object();
      
          public static void Main()
          {
              MethodWithLock();
          }
      
          public static void MethodWithLock()
          {
              lock (_lockObject)
              {
                  Console.WriteLine("Lock acquired. Inside the lock");
                  // Some operation
                  return; // This is allowed
              }
          }
      }
      //在这个例子中,当你调用 MethodWithLock 方法时,它会获取锁,执行 Console.WriteLine 语句,然后 return。在 return 语句执行之前,锁会被释放。
      //注意:在任何 return 语句之前,都会自动释放锁。这是因为 lock 语句是 try-finally 语句的简写,其中释放锁的代码被放在 finally 块中。
      //所以,你可以在 lock 中使用 return 语句,并且不会有任何问题。
      
  • asp.net 跨页面锁的使用
    • 注意⚠️: 此事例经过测试。
    • 测试代码位置: C:\公司\I_ing\git\bjhd2023\Web\test\CrossPageLock1_1.aspx、CrossPageLock1_2.aspx
    • A、定义一个含有锁变量的类,在App_Code目录下面
    namespace Rstone.Test
    {
        public class Locks
        {
            //静态 只读 引用 类型 不是 string
            public static readonly Object Lock1Obj = new Object();
    
            public Locks()
            {
    
            }
        }
    }
    
    • B、页面一使用
    public partial class test_CrossPageLock1_1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            TestLock();
        }
        private void TestLock()
        {
            Response.Write("<br>Before lock");
            Response.Flush();
            lock (Rstone.Test.Locks.Lock1Obj) //锁住上面定义的锁变量
            {
                Response.Write("<br>Locking ...");
                Response.Flush();
                Thread.Sleep(10000);
            }
            Response.Write("<br>After lock.");
            Response.Flush();
        }
    }
    
    • 页面二使用
    public partial class test_CrossPageLock1_2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            TestLock();
        }
    
        private void TestLock()
        {
            Response.Write("<br>Before lock-2");
            Response.Flush();
            lock (Rstone.Test.Locks.Lock1Obj)
            {
                Response.Write("<br>Locking-2 ...");
                Response.Flush();
                Thread.Sleep(10000);
            }
            Response.Write("<br>After lock-2.");
            Response.Flush();
        }
    }