C#的隐藏特征?

C#的隐藏特征?,c#,hidden-features,C#,Hidden Features,在我从中学到以下内容后,我想到了这一点: 我们,C#开发者,都知道C#的基础知识。我指的是声明、条件、循环、运算符等 我们中的一些人甚至掌握了 但是,连C迷、瘾君子和专家都不知道的C最隐藏的特征或技巧是什么 以下是迄今为止显示的特征: 关键词 借 varby 使用()语句 readonlyby asby as/是由 作为/是(改进)的 默认值by global::by 使用() volatileby extern别名by 属性 借 借 借 而且 借 借 借 语法 (合并空值)运算符

在我从中学到以下内容后,我想到了这一点:

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

我们中的一些人甚至掌握了

但是,连C迷、瘾君子和专家都不知道的C最隐藏的特征或技巧是什么

以下是迄今为止显示的特征:

关键词
  • var
    by
  • 使用()语句
  • readonly
    by
  • as
    by
  • as
    /
    是由
  • 作为
    /
    (改进)的
  • 默认值
    by
  • global::
    by
  • 使用()
  • volatile
    by
  • extern别名
    by
属性
  • 而且
语法
  • (合并空值)运算符
  • 按编号标记
  • 其中T:new
    by
  • 隐式泛型
  • 单参数lambdas by
  • 自动属性按
  • 命名空间别名由
  • 带@by的逐字字符串文本
  • 枚举
    值按
  • @变化多端
  • 事件
    操作员
  • 按格式设置字符串括号
  • 属性访问器可访问性修饰符
  • 条件(三元)运算符(
    ?:
    )由
  • 已检查
    未检查
    操作员
  • 隐式和显式
    运算符
语言特征
  • 可为空的类型
  • 匿名类型按
  • \uuuuu makeref\uuuuu reftype\uuuuu refvalue
    by
  • 对象初始值设定项
  • 按设置字符串格式
  • 扩展方法
  • 部分
    方法
  • 预处理器指令
  • 调试
    预处理器指令
  • 运算符重载
  • 类型推断
  • 布尔运算符
  • 将值类型变量作为接口传递,而不通过装箱
  • 通过编程确定声明的变量类型
  • 静态构造函数
  • 使用LINQ by更容易实现眼睛/精简ORM映射
  • \uu arglist
    作者
Visual Studio功能
  • 在编辑器中按选择文本块
  • 片段
框架
  • TransactionScope
    by
  • dependent交易
    by
  • Nullable
    by
  • Mutex
    by
  • System.IO.Path
    by
  • WeakReference
    by
方法和属性
  • String.IsNullOrEmpty()
    方法
  • List.ForEach()
    methodby
  • BeginInvoke()
    EndInvoke()
    方法
  • Nullable.HasValue
    Nullable.Value
    properties by
  • GetValueOrDefault
    方法
小贴士和窍门
  • 事件处理程序的Nice方法
  • 按大小写比较
  • 不通过反射访问匿名类型
  • 一种通过
  • 类似JavaScript的匿名内联函数
其他
  • netmodules by
  • “我会想到的。一些属性,如,也是我的最爱

    “”关键字更为人所知,但您也可以在.NET 2.0应用程序中使用它(只要将其设置为输出2.0代码),这一点似乎并不为人所知

    编辑:kokos,谢谢你指出了??接线员,这真的很有用。由于谷歌搜索有点困难(因为?被忽略),下面是该运营商的MSDN文档页面:

  • -聚结算子
  • 使用(/)-很好的关键字,它不仅可以用于调用Dispose
  • -应该更多地使用
  • netmodules-太糟糕了,Visual Studio中没有支持
  • 我很长一段时间都不知道“as”关键字

    MyClass myObject = (MyClass) obj;
    
    vs


    如果obj不是MyClass,则第二个将返回null,而不是抛出类强制转换异常。

    通常是属性,但最重要的是属性。节省您的时间。

    我倾向于发现大多数C#开发人员不知道“可空”类型。基本上,可以有空值的原语

    double? num1 = null; 
    double num2 = num1 ?? -100;
    
    将可为空的双精度浮点值num1设置为空,然后将常规双精度浮点值num2设置为num1,如果num1为空,则设置为-100

    关于可空类型,还有一件事:

    DateTime? tmp = new DateTime();
    tmp = null;
    return tmp.ToString();
    

    它是return String.Empty。查看链接了解更多详细信息,我对发布这篇文章有点缄默,因为它只不过是吹毛求疵而已。但是,我要指出,在您的代码示例中:

    MyClass c;
      if (obj is MyClass)
        c = obj as MyClass
    
    如果你要用“是”,为什么还要用“as”进行安全转换呢?如果您确定obj确实是MyClass,一个bog标准类型:

    c = (MyClass)obj
    
    …永远不会失败

    同样,你可以说:

    MyClass c = obj as MyClass;
    if(c != null)
    {
       ...
    }
    
    我不太清楚.NET的内部结构,但我的直觉告诉我,这将把最多两个类型强制转换操作减少到最多一个。无论哪种方式,它都不太可能破坏处理库;就个人而言,我认为后一种形式看起来也更干净。

    其他一切,再加上

    1) 隐式泛型(为什么只在方法上而不在类上?)

    3) 匿名类型和初始值设定项:

    //Duck-typed: works with any .Add method.
    var colours = new Dictionary<string, string> {
        { "red", "#ff0000" },
        { "green", "#00ff00" },
        { "blue", "#0000ff" }
    };
    
    int[] arrayOfInt = { 1, 2, 3, 4, 5 };
    

    感谢@pzycoman提醒我:

    5) 命名空间别名(您可能不需要这种特殊的区别):


    下面是一个适用于正则表达式和文件路径的实用工具:

    "c:\\program files\\oldway"
    @"c:\program file\newway"
    

    @告诉编译器忽略字符串中的任何转义字符。

    以下是一些有趣的隐藏C#功能,以未记录的C#关键字的形式出现:

    __makeref
    
    __reftype
    
    __refvalue
    
    __arglist
    
    这些都是未记录的C#关键字(偶数)
    x => x.ToString() //simplify so many calls
    
    //Duck-typed: works with any .Add method.
    var colours = new Dictionary<string, string> {
        { "red", "#ff0000" },
        { "green", "#00ff00" },
        { "blue", "#0000ff" }
    };
    
    int[] arrayOfInt = { 1, 2, 3, 4, 5 };
    
    public int MyId { get; private set; }
    
    using web = System.Web.UI.WebControls;
    using win = System.Windows.Forms;
    
    web::Control aWebControl = new web::Control();
    win::Control aFormControl = new win::Control();
    
    "c:\\program files\\oldway"
    @"c:\program file\newway"
    
    __makeref
    
    __reftype
    
    __refvalue
    
    __arglist
    
    public delegate void MyClickHandler(object sender, string myValue);
    public event MyClickHandler Click = delegate {}; // add empty delegate!
    
    public void DoSomething()
    {
        Click(this, "foo");
    }
    
    public void DoSomething()
    {
        // Unnecessary!
        MyClickHandler click = Click;
        if (click != null) // Unnecessary! 
        {
            click(this, "foo");
        }
    }
    
    string path = dir + "\\" + fileName;
    
    string s = @"cat
                 dog
                 fish"
    
    cat
                 dog
                 fish
    
    private string _name;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
    
    public string Name { get; set;}
    
    Employee emp = new Employee();
    emp.Name = "John Smith";
    emp.StartDate = DateTime.Now();
    
    Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}
    
    T t = default(T);
    
    // Useful? probably not.
    private void foo()
    {
        var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) });
        Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges);
    }
    
    object GetUserTuple()
    {
        return new { Name = "dp", Badges = 5 };
    }    
    
    // Using the magic of Type Inference...
    static T AnonCast<T>(object obj, T t)
    {
       return (T) obj;
    }
    
    var @object = new object();
    var @string = "";
    var @if = IpsoFacto(); 
    
    int foo = 3;
    string bar = "blind mice";
    String.Format("{{I am in brackets!}} {0} {1}", foo, bar);
    //Outputs "{I am in brackets!} 3 blind mice"
    
    string result = value1 ?? value2 ?? value3 ?? String.Empty;
    
    if (x == 1)
    {
       x = 2;
    }
    else
    {
       x = 3;
    }
    
    x = (x==1) ? 2 : 3;
    
    Console.CancelKeyPress +=
        (sender, e) => {
            Console.WriteLine("CTRL+C detected!\n");
            e.Cancel = true;
        };
    
    Func<int, int, EventHandler> makeHandler =
        (dx, dy) => (sender, e) => {
            var btn = (Button) sender;
            btn.Top += dy;
            btn.Left += dx;
        };
    
    btnUp.Click += makeHandler(0, -1);
    btnDown.Click += makeHandler(0, 1);
    btnLeft.Click += makeHandler(-1, 0);
    btnRight.Click += makeHandler(1, 0);
    
    Environment.NewLine
    
    public class MyClass
    {
         public void SomeMethod() { /* Do Something */ }
    }
    
    RegisterMethod(typeof(MyClass), "SomeMethod");
    
    RegisterMethod<MyClass>(cl => cl.SomeMethod());
    
    void RegisterMethod<T>(Expression<Action<T>> action) where T : class
    {
        var expression = (action.Body as MethodCallExpression);
    
        if (expression != null)
        {
            // TODO: Register method
            Console.WriteLine(expression.Method.Name);
        }
    }
    
    private IList<Foo> _foo;
    
    public IList<Foo> ListOfFoo 
        { get { return _foo ?? (_foo = new List<Foo>()); } }
    
    using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;
    
    [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;
    }
    
        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
    
    Environment.FailFast()
    
    public static DeepCopy(this IPrototype p) { ... }