C# 很少人知道的科技
2018-03-19 20:57
357 查看
本文来告诉大家在C#很少有人会发现的科技。即使是工作了好多年的老司机也不一定会知道,如果觉得我在骗你,那么请看看下面
因为C#在微软的帮助,已经从原来很简单的,到现在的很好用。在10多年,很少人知道微软做了哪些,我在网上找了很多大神的博客,然后和很多大神聊天,知道了一些科技,所以就在这里说。如果大家看到这个博客里面没有的科技,请告诉我。
实际上可以无限的使用
可以看到需要写很多代码,如果这个值作为参数,才是可怕。
一个简单的方法是使用
看一下就知道这个定义可以做什么
如果经常使用这两个控件,那么就需要写空间,代码很多,但是微软给了一个坑,使用这个可以不用写空间
参见:https://stackoverflow.com/a/9099/6116637
这时就可以使用 extern alias
参见:C#用extern alias解决两个assembly中相同的类型全名 - fresky - 博客园
注意两个的顺序,反过来直接告诉你代码不能这样写
这样就可以拿到函数的命名
不过在 C# 7.2 都可以使用其他的关键字做到一些,详细请看我的 C# 7.0 博客
但是如果 ToString 被其他地方用了,如何显示?
垃圾微软告诉大家,使用 DebuggerDisplay 特性
他可以使用私有的属性、字段,使用方法很简单
参见Using the DebuggerDisplay Attribute
这时就定义了
这时会输出
参见:自定义数字格式字符串
参见:stackalloc
输出
参见:WPF 判断调用方法堆栈
简单让代码跑一下
结果是什么,大家也知道,在 Debug 和 Release 输出是不相同。但是这么简单的怎么会在这里说,请大家看看这个代码输出什么
实际上在 Release 下什么都不会输出,F1 不会被执行
没错 Foo 没有继承 bool 居然可以这样写
实际上就是重写 true ,请看代码
是不是觉得很多有人这样写,下面让大家看一个很少人会知道的科技,感谢walterlv
这个代码是可以编译通过的,但是只有在我的设备,然后看了这个博客,可能你也可以在你的设备编译
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
因为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
如果想要在调试的时候,鼠标移动到变量显示他的信息,可以重写类的 ToStringpublic 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 下就不会使用 F2public 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 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
相关文章推荐
- C# 很少人知道的科技
- C# 很少人知道的科技 https://blog.csdn.net/lindexi_gd/article/details/79617425
- 你必须知道的C#的25个基础概念
- 有没有人知道怎么把很多Crystal Report(水晶报表)的报表封装成c#的一个DLL
- C#中如何知道编译器的版本
- C#开发人员应该知道的13件事情
- 你必须知道的C#的25个基础概念
- 很少人知道的Linux命令
- 成都领君科技基于ArcEngine10.0+C#开发完成的JLKEngine中间件平台
- 【转】你知道C#中的Lambda表达式的演化过程吗?
- 你必须知道的C#的25个基础概念(附演示)
- 你必须知道的C#的25个基础概念
- C#键盘钩子(我是怎么知道你的密码的?)
- 11 个很少人知道但很有用的 Linux 命令
- 哪位哥哥知道C#程序员哪里找工作好找啊???
- 你知道C#中main函数参数的用处吗?
- 【面向对象语言系列】关于 C# 数据分析,你需要知道的事
- 12个很少被人知道的CSS事实
- 在解析C#结构体指针前,必须知道C#结构体是如何定义的。在c#中同样定义该结构体。