在我从这个问题中了解到以下内容后,我想到了这一点:

where T : struct

我们,C#开发人员,都知道C#的基础知识。我指的是声明、条件、循环、运算符等。

我们中的一些人甚至掌握了Generics、匿名类型、lambdas、LINQ等等。。。

但是,即使是C#的粉丝、瘾君子和专家也几乎不知道C#最隐藏的功能或技巧是什么?

以下是迄今为止揭示的功能:

关键词

迈克尔·斯图姆的产量Michael Stum的varkokos的using()语句kokos只读由Mike Stone作者:Ed Swangren由Rocketpants改进因死亡而违约全球::由pzycomanAlexCuse的using()块Jakubšturc的挥发性Jakubšturc的外部别名

属性

Michael Stum的DefaultValueAttributeDannySmurf的ObsoleteAttribute调试器DisplayAttribute(按Stu)bdukes提供的DebuggerBrowseble和DebuggerStepThroughmarxidad的ThreadStaticAttributeMartin Clarke的FlagsAttributeAndrewBurns的ConditionalAttribute

语法

?? kokos的(合并空值)运算符Nick Berardi的数字标记其中T:Lars Mæhlum的新Keith的隐式泛型Keith的单参数lambdas基思汽车财产Keith的命名空间别名Patrick的带@的逐字字符串文字按lfoost列出的枚举值@marxidad的variableamesmarxidad的事件运算符由Portman设置字符串括号格式xanadot的属性访问器可访问性修饰符JasonS的条件(三元)运算符(?:)Binoj Antony检查和未检查操作员Flory的隐式和显式运算符

语言功能

Brad Barker的可空类型Keith的匿名类型__由Judah Himango制作的makeref __reftype __refvaluelomaxx的对象初始化器达科他州David的字符串格式marxidad的扩展方法Jon Erickson的部分方法John Asbeck的预处理器指令Robert Durgin的DEBUG预处理器指令SefBkn导致操作员过载通过chakrit推断类型Rob Gough将布尔运算符提升到下一级通过Roman Boiko将值类型变量作为不带装箱的接口传递由Roman Boiko编程确定声明的变量类型Chris的静态构造器使用LINQ by roosteronacid更容易进行眼睛/精简ORM映射__Zac Bowling的arglist

Visual Studio功能

Himadri在编辑器中选择文本块DannySmurf的片段

框架

KiwiCastard的TransactionScopeKiwiAstard的从属事务IainMH的<T>可为空迪亚戈的Mutex按ageektrapped列出的System.IO.PathJuan Manuel的WeakReference

方法和财产

KiwiAstard的String.IsNullOrEmpty()方法KiwiCastard的List.ForEach()方法Will Dean的BeginInvoke()、EndInvoke(()方法Nullable<T>。HasValue和Nullable<T>。Rismo的Value财产John Sheehan的GetValueOrDefault方法

提示和技巧

Andreas H.R.Nilsson的事件处理程序的好方法John的大写比较访问匿名类型而不通过dp进行反射Will延迟实例化集合财产的快速方法chosteronacid提供的类似JavaScript的匿名内联函数

另外

kokos的netmodulesDuncan Smart的LINQBridgeJoel Coehorn的并行扩展


当前回答

别名泛型:

using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;

它允许您使用ASimpleName,而不是Dictionary<string,Dictionary>string,List<string>>。

当你在很多地方使用同一个通用的大而长的复杂的东西时,可以使用它。

其他回答

C#+CLR:

Thread.MemoryBarrier:大多数人不会使用它,MSDN上有一些不准确的信息。但如果您了解复杂性,那么您可以进行漂亮的无锁同步。volatile、Thread.volatile阅读、Thread.Wolatile写作:很少有人能够使用这些工具,更没有人能够理解他们避免和引入的所有风险:)。ThreadStatic变量:在过去几年中,我发现只有一种情况是ThreadStatic绝对是天赐的,是不可或缺的。例如,当您想为整个呼叫链做一些事情时,它们非常有用。fixed关键字:当您想以几乎与C++一样快的速度访问大型数组的元素时,这是一个隐藏的武器(默认情况下,C#强制执行绑定检查,以降低速度)。default(typeName)关键字也可以在泛型类之外使用。创建结构的空副本很有用。我使用的一个方便的特性是DataRow[columnName].ToString()总是返回非空值。若数据库中的值为NULL,则得到空字符串。当您希望开发人员注意时,即使尚未启用异常自动中断,也可以使用调试器对象自动中断:


#if DEBUG  
    if (Debugger.IsAttached)  
        Debugger.Break();  
#endif

您可以对复杂的难看的泛型类型进行别名,这样就不必反复复制粘贴它们。您还可以在一个位置对该类型进行更改。例如


    using ComplicatedDictionary = Dictionary<int, Dictionary<string, object>>;
    ComplicatedDictionary myDictionary = new ComplicatedDictionary();

如果要退出程序而不调用任何finally块或终结器,请使用FailFast:

Environment.FailFast()

当您想要调用/BegginInvoke内联代码时,内置(2.0)MethodInvoker委托非常有用。这避免了需要创建实际的委托和单独的方法。

    void FileMessageEvent(object sender, MessageEventArgs e)
    {

        if (this.InvokeRequired == true)
        {
            this.BeginInvoke((MethodInvoker)delegate { 
                     lblMessage.Text=e.Message; 
                     Application.DoEvents(); 
                 }
            ); 

        }
    }

解决错误:“无法将匿名方法转换为类型”System.Delegate“,因为它不是委托类型”。

还不确定是否提到了这一点,但ThreadStatic属性是一个非常有用的属性。这使得静态字段仅对当前线程是静态的。

[ThreadStatic]
private static int _ThreadStaticInteger;

您不应该包含初始值设定项,因为它只在整个应用程序中执行一次,所以最好将字段设置为空,并在使用它之前检查该值是否为空。

此外,ASP.NET应用程序线程还有一点是重用的,因此如果您修改该值,它可能最终被用于另一个页面请求。

尽管如此,我还是多次发现这一点很有用。例如,在创建自定义事务类时:

using (DbTransaction tran = new DbTransaction())
{
    DoQuery("...");
    DoQuery("...");    
}

DbTransaction构造函数将ThreadStatic字段设置为其自身,并在dispose方法中将其重置为null。DoQuery检查静态字段,如果!=null使用当前事务,如果不是,则默认为其他事务。我们避免了必须将事务传递给每个方法,而且它可以很容易地包装原本不打算用于事务内部事务的其他方法。。。

只需一次使用:)

纯安全C中的联合(C++共享内存类型)#

在不使用不安全模式和指针的情况下,可以让类成员共享类/结构中的内存空间。给定以下类别:

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

您可以通过操作Int32字段来修改字节字段的值,反之亦然。例如,该程序:

    static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

输出以下内容:

2147483647
FF FF FF 7F
65535

只需添加使用System.Runtime.InteropServices;