C#/.Net · 2020年5月18日 0

C#.Net 奇淫巧计——不常用但很有用

C#.Net 奇淫巧计——不常用但很有用

Activator
Activator.CreateInstance(typeof(Indexmodel));

包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。使用场景颇多。

MSDN

TransactionScope
using (TransactionScope scope = new TransactionScope())
{
    scope.Complete();
}

使代码块成为事务性代码。可以替代ORM自带的事务。

MSDN

DependentTransaction
public class WorkerThread  
{  
    public void DoWork(DependentTransaction dependentTransaction)  
    {  
        Thread thread = new Thread(ThreadMethod);  
        thread.Start(dependentTransaction);
    }  

    public void ThreadMethod(object transaction)
    {
        DependentTransaction dependentTransaction = transaction as DependentTransaction;  
        Debug.Assert(dependentTransaction != null);
        try  
        {  
            using(TransactionScope ts = new TransactionScope(dependentTransaction))  
            {  
                /* Perform transactional work here */
                ts.Complete();  
            }  
        }  
        finally  
        {  
            dependentTransaction.Complete();
             dependentTransaction.Dispose();
        }  
    }  

//Client code
using(TransactionScope scope = new TransactionScope())  
{  
    Transaction currentTransaction = Transaction.Current;  
    DependentTransaction dependentTransaction;
    dependentTransaction = currentTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete);  
    WorkerThread workerThread = new WorkerThread();  
    workerThread.DoWork(dependentTransaction);  
    /* Do some transactional work here, then: */  
    scope.Complete();  
} 

描述事务的克隆,该克隆保证在应用程序停止事务上的工作之后才能提交事务。主要用于管理并发。

MSDN

MSDN-使用 DependentTransaction 管理并发

Tuple
var population = new Tuple(
                           "New York", 7891957, 7781984, 
                           7894862, 7071639, 7322564, 8008278);

提供用于创造元组对象的静态方法。说人话:可以创建包含多种不类型的集合。可以当作方法的返回值。

同时还有一个ValueTuple,有些许区别。

MSDN-Tuple

MSDN-ValueTuple

HashSet

提供了高性能的设置操作。 集是不包含重复元素的集合,其元素无特定顺序。

MSDN

关于数组与KV类型的类,官方有以下建议:

For new code, you shouldn’t use non-generic collections:

  • Error prone: since non-generic collections are untyped, it requires frequent casting between and the actual type you're expecting. Since the compiler can't check that your types are consistent, it's easier to put the wrong type in the wrong collection.object
  • Less performant: generic collections have the advantage that value types don't have to be boxed as object. For instance, a stores its data in an . That's far better than storing the data in as that requires boxing.List``int[]``object[]

The following table shows how the non-generic collection types can be replaced by their generic counterparts from the System.Collections.Generic or System.Collections.ObjectModel namespaces:

Type Replacement
ArrayList List
CaseInsensitiveComparer StringComparer.OrdinalIgnoreCase
CaseInsensitiveHashCodeProvider StringComparer.OrdinalIgnoreCase
CollectionBase Collection
Comparer Comparer
DictionaryBase Dictionary or KeyedCollection
DictionaryEntry KeyValuePair
Hashtable Dictionary
Queue Queue
ReadOnlyCollectionBase ReadOnlyCollection
SortedList SortedList
Stack Stack

说简单点,左边应该被替换为右边的。

详见:GitHub

DefaultValueAttribute
[DefaultValue(false)]
public bool MyProperty { get; set; }

指定属性的默认值。DefaultValueAttribute 不会导致成员自动使用特性的值初始化。 你必须在代码中设置初始值。

MSDN

Lazy\
static void Main(string[] args)
{
    System.Lazy a = new Lazy(() => GetArr());
    Console.WriteLine($"数组是否创建:{a.IsValueCreated}");
    var aArr = a.Value;
    foreach (var item in aArr)
    {
        Console.WriteLine($"value:{item}");
    }
    Console.WriteLine($"数组是否创建:{a.IsValueCreated}");
}
public static int[] GetArr()
{
    return new int[] { 1, 2, 3 };
}
//数组是否创建:False
//value:1
//value:2
//value:3
//数组是否创建:True

提供对延迟初始化的支持。当业务中有需要加载对象,但不需要立即使用时,可以使用Lazy对象来延迟加载。以此提高程序的效率,从而使程序占用更少的内存。

MSDN

extern-关键字
[DllImport("avifil32.dll")]
private static extern void AVIFileInit();

extern 修饰符用于声明在外部实现的方法。 extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。 在这种情况下,还必须将方法声明为 static,如下面的示例所示:

CSDN

yield-关键字
public static class GalaxyClass
{
    public static void ShowGalaxies()
    {
        var theGalaxies = new Galaxies();
        foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
        {
            Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
        }
    }

    public class Galaxies
    {

        public System.Collections.Generic.IEnumerable NextGalaxy
        {
            get
            {
                yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
                yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
                yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
                yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
            }
        }
    }

    public class Galaxy
    {
        public String Name { get; set; }
        public int MegaLightYears { get; set; }
    }
}

可在实现自定义集合类型的 IEnumeratorIEnumerable 模式时无需其他显式类

MSDN

volatile-关键字
class VolatileTest{    public volatile int sharedStorage;    public void Test(int _i)    {        sharedStorage = _i;    }}

volatile 关键字指示一个字段可以由多个同时执行的线程修改。 出于性能原因,编译器,运行时系统甚至硬件都可能重新排列对存储器位置的读取和写入。 声明了 volatile 的字段不进行这些优化。 添加 volatile 修饰符可确保所有线程观察易失性写入操作(由任何其他线程执行)时的观察顺序与写入操作的执行顺序一致。 不确保从所有执行线程整体来看时所有易失性写入操作均按执行顺序排序。

简单说就是使用volatile修饰的字段,可以由多个线程修改,并且各个线程读取时都是从主内存中获取值。

MSDN

System.Collections.Concurrent-命名空间

System.Collections.Concurrent 命名空间提供多个线程安全集合类。当有多个线程并发访问集合时,应使用这些类代替 System.CollectionsSystem.Collections.Generic 命名空间中的对应类型。

Class 说明
BlockingCollection 为实现 IProducerConsumerCollection 的线程安全集合提供阻塞和限制功能。
ConcurrentBag 表示对象的线程安全的无序集合。
ConcurrentDictionary 表示可由多个线程同时访问的键/值对的线程安全集合。
ConcurrentQueue 表示线程安全的先进先出 (FIFO) 集合。
ConcurrentStack 表示线程安全的后进先出 (LIFO) 集合。
OrderablePartitioner 表示将可排序数据源拆分为多个分区的特定方式。
Partitioner 为数组、列表和可枚举对象提供常见的分区策略。
Partitioner 表示将数据源拆分为多个分区的特定方式。

MSDN

Path.Combine
string[] paths = {@"d:\archives", "2001", "media", "images"};
string fullPath = Path.Combine(paths);
Console.WriteLine(fullPath);            

paths = new string[] {@"d:\archives\", @"2001\", "media", "images"};
fullPath = Path.Combine(paths);
Console.WriteLine(fullPath); 

paths = new string[] {"d:/archives/", "2001/", "media", "images"};
fullPath = Path.Combine(paths);
Console.WriteLine(fullPath); 
// The example displays the following output if run on a Windows system:
//    d:\archives\2001\media\images
//    d:\archives\2001\media\images
//    d:/archives/2001/media\images
//
// The example displays the following output if run on a Unix-based system:
//    d:\archives/2001/media/images
//    d:\archives\/2001\/media/images
//    d:/archives/2001/media/images   

将多个字符串组合成一个路径。此方法旨在将各个字符串连接到表示文件路径的单个字符串。 但是,如果第一个参数不包含一个根路径,则将忽略以前的任何路径组件,并且返回的字符串将以该根路径组件开头。

当再次遇到无法确定路径是用</code>还是/时,建议使用此方法自动拼接。

URL也由雷同的一个方法。

MSDN






>>转载请注明原文链接地址:C#.Net 奇淫巧计——不常用但很有用