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

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的并行扩展


当前回答

不是C#的具体内容,但我是一个三元操作迷。

而不是

if (boolean Condition)
{
    //Do Function
}
else
{
    //Do something else
}

你可以用一个简洁的

booleanCondtion ? true operation : false operation;

e.g.

而不是

int value = param;
if (doubleValue)
{
    value *= 2;
}
else
{
    value *= 3;
}

您可以键入

int value = param * (tripleValue ? 3 : 2);

它确实有助于编写简洁的代码,但嵌套这些该死的东西可能会令人讨厌,它们可能会被用于邪恶,但我还是喜欢那些小笨蛋

其他回答

C#3.0的LINQ查询综合是一个完整的一元综合,就像Haskell(事实上,它们是由Haskell的一位设计师设计的)。它们将适用于遵循“LINQ模式”的任何泛型类型,并允许您以纯一元函数样式编写,这意味着所有变量都是不可变的(就像在using和foreach语句中使用的唯一变量是IDisposable和IEnumerable一样)。这有助于保持变量声明接近其使用位置,并确保显式声明所有副作用(如果有的话)。

 interface IFoo<T>
  { T Bar {get;}
  }

 class MyFoo<T> : IFoo<T> 
  { public MyFoo(T t) {Bar = t;}
    public T Bar {get; private set;} 
  }

 static class Foo 
  { public static IFoo<T> ToFoo<T>(this T t) {return new MyFoo<T>(t);}

    public static void Do<T>(this T t, Action<T> a) { a(t);}

    public static IFoo<U> Select<T,U>(this IFoo<T> foo, Func<T,U> f) 
     { return f(foo.Bar).ToFoo();
     }
  }

 /* ... */

 using (var file = File.OpenRead("objc.h"))
 { var x = from f in file.ToFoo()
           let s = new Scanner(f)
           let p = new Parser {scanner = s}
           select p.Parse();

   x.Do(p => 
    { /* drop into imperative code to handle file 
         in Foo monad if necessary */      
    });

 }

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();

混合物。基本上,如果您想向多个类添加一个特性,但不能对所有类使用一个基类,请让每个类实现一个接口(没有成员)。然后,为接口编写一个扩展方法,即。

public static DeepCopy(this IPrototype p) { ... }

当然,牺牲了一些清晰度。但它奏效了!

我喜欢的一个很棒的类是System.Xml.XmlConvert,它可以用于从Xml标记中读取值。特别是,如果我从xml属性或元素中读取布尔值,我使用

bool myFlag  = System.Xml.XmlConvert.ToBoolean(myAttribute.Value);

注意:由于xml中的布尔类型接受1和0以及“true”和“false”作为有效值,因此在这种情况下使用字符串比较容易出错。

我今天才知道这一点——我已经和C#合作5年了!

这是命名空间别名限定符:

extern alias YourAliasHere;

您可以使用它加载同一类型的多个版本。这在维护或升级场景中非常有用,因为您的类型有一个更新版本,在某些旧代码中无法使用,但您需要将其升级到新版本。敲击命名空间别名限定符,编译器将允许您在代码中同时使用这两种类型。