C# 很少人知道的科技

来源:https://www.cnblogs.com/lindexi/archive/2018/03/19/cs-few-people-will-be-able.html
-Advertisement-
Play Games

本文來告訴大家在C#很少有人會發現的科技。即使是工作了好多年的老司機也不一定會知道,如果覺得我在騙你,那麼請看看下麵 ...


本文來告訴大家在C#很少有人會發現的科技。即使是工作了好多年的老司機也不一定會知道,如果覺得我在騙你,那麼請看看下麵

因為C#在微軟的幫助,已經從原來很簡單的,到現在的很好用。在10多年,很少人知道微軟做了哪些,我在網上找了很多大神的博客,然後和很多大神聊天,知道了一些科技,所以就在這裡說。如果大家看到這個博客裡面沒有的科技,請告訴我。

無限級判斷空

在 C# 6.0 可以使用??判斷空,那麼就可以使用下麵代碼

            var v1 = "123";
            string v2 = null;
            string v3 = null;

            var v = v1 ?? v2 ?? v3;

實際上可以無限的使用??

using 省略長的定義

例如有這個代碼,使用了很多的 List ,裡面有很多定義

var foo =
                new System.Collections.Generic.Dictionary<
                    System.Collections.Generic.List<System.Collections.Generic.List<string>>, string>();

可以看到需要寫很多代碼,如果這個值作為參數,才是可怕。

一個簡單的方法是使用 using HvcnrclHnlfk= System.Collections.Generic.Dictionary<System.Collections.Generic.List<System.Collections.Generic.List<string>>,string>; ,這個文件里的所有定義都可以使用 using 後面的值可以代替。

var foo = new HvcnrclHnlfk();

辣麽大

實際上我有些不好意思,好像剛剛說的都是大家都知道的,那麼我就要開始寫大家很少知道

          Func<string,string, EventHandler> foo = (x, y) => (s, e) =>
            {
                var button = (Button) s;
                button.Left = x;
                button.Top = y;
            };

            Button1.Click += foo(0, -1);

看一下就知道這個定義可以做什麼

千萬不要告訴我,你覺得上面編譯不通過,實際上我用了黑科技

但是不告訴你

衝突的類型

如果遇到兩個命名空間相同的類型,很多時候都是把命名空間全寫

var webControl = new System.Web.UI.WebControls.Control();
var formControl = new System.Windows.Forms.Control();

如果經常使用這兩個控制項,那麼就需要寫空間,代碼很多,但是微軟給了一個坑,使用這個可以不用寫空間

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control webControl = new web::Control();
win::Control formControl = new win::Control();

參見:https://stackoverflow.com/a/9099/6116637

extern alias

如果使用了兩個 dll ,都有相同命名空間和類型,那麼如何使用指定的庫

//a.dll

namespace F
{
    public class Foo
    {

    }
}

//b.dll

namespace F
{
    public class Foo
    {
        
    }
}

這時就可以使用 extern alias

參見:C#用extern alias解決兩個assembly中相同的類型全名 - fresky - 博客園

字元串

大家看到了 C# 6.0 的$,是不是可以和@一起?

            var str = "kktpqfThiq";
            string foo = $@"換行
{str}";

註意兩個的順序,反過來直接告訴你代碼不能這樣寫

表達式樹獲取函數命名

定義一個類,下麵通過表達式樹從類獲得函數命名

    class Foo
    {
        public void KzcSevfio()
        {
        }
    }
       static void Main(string[] args)
        {
            GetMethodName<Foo>(foo => foo.KzcSevfio());
        }

        private static void GetMethodName<T>(Expression<Action<T>> action) where T : class
        {
            if (action.Body is MethodCallExpression expression)
            {
                Console.WriteLine(expression.Method.Name);
            }
        }

這樣就可以拿到函數的命名

特殊關鍵字

實際上有下麵幾個關鍵字是沒有文檔,可能只有垃圾微軟的編譯器才知道

__makeref

__reftype

__refvalue

__arglist

不過在 C# 7.2 都可以使用其他的關鍵字做到一些,詳細請看我的 C# 7.0 博客

DebuggerDisplay

如果想要在調試的時候,滑鼠移動到變數顯示他的信息,可以重寫類的 ToString

    public sealed class Foo
    {
        public int Count { get; set; }

        public override string ToString()
        {
            return Count.ToString();
        }
    }

但是如果 ToString 被其他地方用了,如何顯示?

垃圾微軟告訴大家,使用 DebuggerDisplay 特性

    [DebuggerDisplay("{DebuggerDisplay}")]
    public sealed class Foo
    {
        public int Count { get; set; }

        private string DebuggerDisplay => $"(count {Count})";
    }

他可以使用私有的屬性、欄位,使用方法很簡單

參見Using the DebuggerDisplay Attribute

使用 Unions (C++ 一樣的)

如果看到 C++ 可以使用內聯,不要說 C# 沒有,實際上也可以使用 FieldOffset ,請看下麵

[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;
}

這時就定義了int變數,修改他就是修改其他的三個

     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

介面預設方法

實際上可以給介面使用預設方法,使用的方式

public static void Foo(this IF1 foo)
{
     //實際上大家也看到是如何定義
}

數字格式

string format = "000;-#;(0)";

string pos = 1.ToString(format);     // 001
string neg = (-1).ToString(format);  // -1
string zer = 0.ToString(format);     // (0)

參見:自定義數字格式字元串

stackalloc

實際上很多人都不知道這個,這是不安全代碼,從棧申請空間

int* block = stackalloc int[100]; 

參見:stackalloc

調用堆棧

如果需要獲得調用方法的堆棧,可以使用這個文章的方法

  class Program
    {
        static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1();
        }
    }

    public sealed class Foo
    {
        public void F1()
        {
            F2();
        }

        void F2()
        {
            var stackTrace = new StackTrace();
            var n = stackTrace.FrameCount;
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine(stackTrace.GetFrame(i).GetMethod().Name);
            }
        }
    }

輸出

F2
F1

參見:WPF 判斷調用方法堆棧

指定編譯

如果使用 Conditional 可以讓代碼在指定條件不使用,我寫了這個代碼,在 Release 下就不會使用 F2

    public sealed class Foo
    {
        public Foo F1()
        {
            Console.WriteLine("進入F1");
            return this;
        }

        [Conditional("DEBUG")]
        public void F2()
        {
            Console.WriteLine("F2");
        }
    }

簡單讓代碼跑一下

        static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1();
            foo.F2();
        }

結果是什麼,大家也知道,在 Debug 和 Release 輸出是不相同。但是這麼簡單的怎麼會在這裡說,請大家看看這個代碼輸出什麼

     static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1().F2();
        }

實際上在 Release 下什麼都不會輸出,F1 不會被執行

true 判斷

下麵寫個見鬼的代碼

            var foo = new Foo(10);

            if (foo)
            {
                Console.WriteLine("我的類沒有繼承 bool ,居然可以這樣寫");
            }

沒錯 Foo 沒有繼承 bool 居然可以這樣寫

實際上就是重寫 true ,請看代碼

    public class Foo
    {
        public Foo(int value)
        {
            _count = value;
        }

        private readonly int _count;

        public static bool operator true(Foo mt)
        {
            return mt._count > 0;
        }

        public static bool operator false(Foo mt)
        {
            return mt._count < 0;
        }
    }

是不是覺得很多有人這樣寫,下麵讓大家看一個很少人會知道的科技,感謝walterlv

await 任何類型

await "林德熙逗比";

await "不告訴你";

這個代碼是可以編譯通過的,但是只有在我的設備,然後看了這個博客,可能你也可以在你的設備編譯

變數名使用中文

實際上在C#支持所有 Unicode ,所以變數名使用中文也是可以的,而且可以使用特殊的字元

        public string H\u00e5rføner()
        {
            return "可以編譯";
        }

知識共用許可協議
本作品採用知識共用署名-非商業性使用-相同方式共用 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發佈,但務必保留文章署名林德熙(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我聯繫


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 調用函數 標準的PHP發行包中有1000多個標準函數 假設函數庫已經編譯到安裝發行包中或include()或require()語句包含了相應的函數庫,就可以指定函數名調用函數 計算5的3次方,就可以調用PHP的pow()函數 也可以不把值賦給變數,而是直接輸出 也可以進行拼接 或者使用printf( ...
  • Python很火,我也下了個來耍耍一陣子。可是漸漸地,我已經不滿足於它的基本庫了,我把目光轉到了Numpy~~~~~ 然而想法總是比現實容易,因為我之前下的是Python3.3.x,所有沒有自帶pip!!!(這裡得插一句:很多人以為Python都是自帶pip的,之前的我也是(掩臉笑),印象中是Pyt ...
  • Make a simple custom EventEmitter ...
  • 1,abs 求絕對值 2,max, min求序列最大值與最小值 3,len求列表的長度 4,divmod求商和餘數 5,pow,兩個值,冪運算,3個值,先冪運算,再除以第三個值,求餘數 6,callable測試函數是否可以被調用 7,類型判斷 也可以用isinstance判斷 8,cmp比較字元串大 ...
  • 單例模式 單例模式(Singleton Pattern)是一種常用的軟體設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當希望在整個系統中,某個類只能出現一個實例時,單例對象就能派上用場。 比如,某個伺服器程式的配置信息存放在一個文件中,客戶端通過一個 AppConfig 的類來讀取配置文 ...
  • 因Excel催化劑用了VSTO的開發技術,並且為了最好的用戶體驗,用了Clickonce的佈署方式(無需人工干預自動更新,讓用戶使用如瀏覽器訪問網站一般,永遠是最新的內容和功能)。對安裝過程有一定的難度要求。僅以此文簡單羅列一下,希望能夠給廣大用戶一些實質性的指引(安裝成功過Excel催化劑插件或安 ...
  • 在使用騰訊雲對象存儲之前,公司一直使用的是傳統的FTP的上傳模式,而隨著用戶量的不斷增加,FTP所暴露出來的問題也越來越多,1.傳輸效率低,上傳速度慢。2.時常有上傳其他文件來攻擊伺服器,安全上得不到保障。所以我們在經過慎重考慮覺得使用第三方的雲存儲服務。 在最開始的時候我們在騰訊雲與阿裡雲中選擇, ...
  • 去年12月份,隨著Visual Studio 2017 Update 15.5的發佈,Visual C#迎來了它的最新版本:7.2. 在這個版本中,有個讓人難以理解的新特性,就是private protected訪問修飾符(Access Modifier)。至此,C#語言的訪問修飾符有以下幾種: p ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...