Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
CSDN 技术社区
skill_tree_dotnet
提交
0e67cb44
S
skill_tree_dotnet
项目概览
CSDN 技术社区
/
skill_tree_dotnet
通知
30
Star
6
Fork
4
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
2
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
skill_tree_dotnet
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
2
Issue
2
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
0e67cb44
编写于
3月 15, 2022
作者:
F
feilong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
增加C#5。0
上级
e1dcb664
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
480 addition
and
58 deletion
+480
-58
data/1..NET初阶/3.C#特性/2.C#4.0特性/Dynamic.json
data/1..NET初阶/3.C#特性/2.C#4.0特性/Dynamic.json
+8
-0
data/1..NET初阶/3.C#特性/2.C#4.0特性/Dynamic.md
data/1..NET初阶/3.C#特性/2.C#4.0特性/Dynamic.md
+62
-0
data/1..NET初阶/3.C#特性/2.C#4.0特性/config.json
data/1..NET初阶/3.C#特性/2.C#4.0特性/config.json
+3
-2
data/1..NET初阶/3.C#特性/2.C#4.0特性/sample/Program.cs
data/1..NET初阶/3.C#特性/2.C#4.0特性/sample/Program.cs
+78
-48
data/1..NET初阶/3.C#特性/3.C#5.0特性/AsyncAwait.json
data/1..NET初阶/3.C#特性/3.C#5.0特性/AsyncAwait.json
+8
-0
data/1..NET初阶/3.C#特性/3.C#5.0特性/AsyncAwait.md
data/1..NET初阶/3.C#特性/3.C#5.0特性/AsyncAwait.md
+138
-0
data/1..NET初阶/3.C#特性/3.C#5.0特性/CallerInfo.json
data/1..NET初阶/3.C#特性/3.C#5.0特性/CallerInfo.json
+8
-0
data/1..NET初阶/3.C#特性/3.C#5.0特性/CallerInfo.md
data/1..NET初阶/3.C#特性/3.C#5.0特性/CallerInfo.md
+104
-0
data/1..NET初阶/3.C#特性/3.C#5.0特性/config.json
data/1..NET初阶/3.C#特性/3.C#5.0特性/config.json
+8
-6
data/1..NET初阶/3.C#特性/3.C#5.0特性/sample/Program.cs
data/1..NET初阶/3.C#特性/3.C#5.0特性/sample/Program.cs
+51
-0
data/1..NET初阶/3.C#特性/3.C#5.0特性/sample/sample.csproj
data/1..NET初阶/3.C#特性/3.C#5.0特性/sample/sample.csproj
+10
-0
data/tree.json
data/tree.json
+2
-2
未找到文件。
data/1..NET初阶/3.C#特性/2.C#4.0特性/Dynamic.json
0 → 100644
浏览文件 @
0e67cb44
{
"type"
:
"code_options"
,
"author"
:
"huanhuilong"
,
"source"
:
"Covariance.md"
,
"notebook_enable"
:
false
,
"exercise_id"
:
"5e0d3fafff5f414681d29c840d3d24f5"
}
\ No newline at end of file
data/1..NET初阶/3.C#特性/2.C#4.0特性/Dynamic.md
0 → 100644
浏览文件 @
0e67cb44
# dynamic 类型
下面的代码在编译时时错误的:
```
csharp
// 编译错误,object和int不能相加
object
n
=
10
;
int
result
=
n
+
5
;
Console
.
WriteLine
(
"result:{0}"
,
result
);
```
而下面的代码可以在编译时通过,运行时正常执行:
```
csharp
// 编译时不检查类型,运行时才检查
dynamic
n
=
10
;
int
result
=
n
+
5
;
Console
.
WriteLine
(
"result:{0}"
,
result
);
```
dynamic 的用途就是在编译时忽略类型检查,延迟到运行期再检查。现在有下面的代码
```
csharp
class
Test
{
public
static
dynamic
Double
(
dynamic
d
){
if
(
d
is
int
){
return
d
*
2
;
}
else
if
(
d
is
string
){
return
d
+
d
;
}
else
{
throw
new
Exception
(
"Not support"
);
}
}
}
```
以下关于 上述 dynamic 的代码调用,运行时会出错的是?
## 答案
```
csharp
Console
.
WriteLine
(
Test
.
Double
(
new
object
()));
```
## 选项
### A
```
csharp
Console
.
WriteLine
(
Test
.
Double
(
10
));
```
### B
```
csharp
Console
.
WriteLine
(
Test
.
Double
(
"10"
));
```
### C
```
csharp
Console
.
WriteLine
(
Test
.
Double
(
10
/
2
));
```
\ No newline at end of file
data/1..NET初阶/3.C#特性/2.C#4.0特性/config.json
浏览文件 @
0e67cb44
{
"node_id"
:
"csharp-d4650354f5f5498e9969fd98bbb40323"
,
"keywords"
:
[
"
协变和逆变
"
,
"
dynamic
"
,
"命名参数"
,
"可选参数"
,
"
动态查找
"
"
协变和逆变
"
],
"children"
:
[],
"export"
:
[
"Dynamic.json"
,
"OptionParam.json"
,
"NamedParam.json"
,
"Covariance.json"
,
...
...
data/1..NET初阶/3.C#特性/2.C#4.0特性/sample/Program.cs
浏览文件 @
0e67cb44
// See https://aka.ms/new-console-template for more information
Console
.
WriteLine
(
"Hello, World!"
);
Console
.
WriteLine
(
Test
.
Double
(
10
/
2
));
// Console.WriteLine(Test.Double("10"));
// Console.WriteLine(Test.Double(new object()));
class
Test
{
public
static
dynamic
Double
(
dynamic
d
){
if
(
d
is
int
){
return
d
*
2
;
}
else
if
(
d
is
string
){
return
d
+
d
;
}
else
{
throw
new
Exception
(
"Not support"
);
}
}
}
// 编译错误
// object n = 10;
// int result = n + 5;
// Console.WriteLine("result:{0}", result);
// 编译时不检查,运行时才检查
// dynamic n = "10";
// int result = n + 5;
// Console.WriteLine("result:{0}", result);
// // // 协变代码
// ISearch<Article> search = new CodeArticleSearch<CodeArticle>();
// Article article = search.Search();
...
...
@@ -18,50 +48,50 @@ Console.WriteLine("Hello, World!");
// Test.Find(key:"hello", number:5);
Test
.
Find
(
key
:
"hello"
,
sort
:
false
,
number
:
5
);
Test
.
Find
(
sort
:
false
,
number
:
5
,
key
:
"hello"
);
static
class
Test
{
public
static
List
<
string
>
Find
(
string
key
,
int
number
,
bool
sort
){
Console
.
WriteLine
(
"key:{0}, number:{1}, sort:{2}"
,
key
,
number
,
sort
);
return
new
List
<
string
>(){};
}
}
// 父类和子类
class
Article
{
public
string
ToString
(){
return
"article"
;
}
}
class
CodeArticle
:
Article
{
public
string
ToString
(){
return
"article with code"
;
}
}
// 协变
public
interface
ISearch
<
out
T
>
{
T
Search
();
}
public
class
CodeArticleSearch
<
T
>:
ISearch
<
T
>
where
T
:
new
(){
public
T
Search
(){
return
new
T
();
}
}
// 逆变
public
interface
ISend
<
in
T
>
{
void
Send
(
T
t
);
}
public
class
ArticleSender
<
T
>
:
ISend
<
T
>{
public
void
Send
(
T
t
){
Console
.
WriteLine
(
"Send:{0}"
,
t
.
ToString
());
}
}
\ No newline at end of file
// Test.Find(key:"hello", sort:false, number:5);
// Test.Find(sort:false, number:5, key:"hello");
// static class Test{
// public static List<string> Find(string key, int number, bool sort){
// Console.WriteLine("key:{0}, number:{1}, sort:{2}", key, number, sort);
// return new List<string>(){};
// }
// }
// // 父类和子类
// class Article{
// public string ToString(){
// return "article";
// }
// }
// class CodeArticle: Article{
// public string ToString(){
// return "article with code";
// }
// }
// // 协变
// public interface ISearch<out T> {
// T Search();
// }
// public class CodeArticleSearch<T>: ISearch<T> where T:new(){
// public T Search(){
// return new T();
// }
// }
// // 逆变
// public interface ISend<in T> {
// void Send(T t);
// }
// public class ArticleSender<T> : ISend<T>{
// public void Send(T t){
// Console.WriteLine("Send:{0}", t.ToString());
// }
// }
\ No newline at end of file
data/1..NET初阶/3.C#特性/3.C#5.0特性/AsyncAwait.json
0 → 100644
浏览文件 @
0e67cb44
{
"type"
:
"code_options"
,
"author"
:
"huanhuilong"
,
"source"
:
"AsyncAwait.md"
,
"notebook_enable"
:
false
,
"exercise_id"
:
"857ced4d29204906b695e8b97ff914ee"
}
\ No newline at end of file
data/1..NET初阶/3.C#特性/3.C#5.0特性/AsyncAwait.md
0 → 100644
浏览文件 @
0e67cb44
# 异步任务(async, await, Task)
下面的代码是同步执行的:
```
csharp
// 同步
Console
.
WriteLine
(
"调用 DoSomethingSync 之前"
);
DoSomethingSync
();
Console
.
WriteLine
(
"调用 DoSomethingSync 之后"
);
void
DoSomethingSync
(){
Thread
.
Sleep
(
1000
);
Console
.
WriteLine
(
"等我一秒钟"
);
}
```
输出的结果是:
```
csharp
调用
DoSomethingSync
之前
等我一秒钟
调用
DoSomethingSync
之后
```
而下面的代码是异步执行的:
```
csharp
// 异步
Console
.
WriteLine
(
"调用 DoSomethingAsync 之前"
);
Task
task
=
DoSomethingAsync
();
Console
.
WriteLine
(
"调用 DoSomethingAsync 之后"
);
await
task
;
async
Task
DoSomethingAsync
(){
await
Task
.
Delay
(
10000
);
Console
.
WriteLine
(
"等我一秒钟"
);
}
```
输出结果是:
```
csharp
调用
DoSomethingAsync
之前
调用
DoSomethingAsync
之后
等我一秒钟
```
几个关键的地方是
*
async 方法必须返回一个Task
*
一个 Task 可以被异步执行,程序继续往下执行主线逻辑
*
一个 Task,可以被 await(异步等待)
*
通过 await 一个Task,则必须等待异步任务完成后才继续往下执行
下面关于 async, await 说法错误的是?
## 答案
```
csharp
// 以下代码的输出是
// ==
// "调用 DoSomethingAsync 之前"
// "调用 DoSomethingAsync 之后"
// "等我一秒钟"
//
Console
.
WriteLine
(
"调用 DoSomethingAsync 之前"
);
Task
task
=
DoSomethingAsync
();
Console
.
WriteLine
(
"调用 DoSomethingAsync 之后"
);
await
task
;
async
Task
DoSomethingAsync
(){
await
Thread
.
Sleep
(
1000
);
Console
.
WriteLine
(
"等我一秒钟"
);
}
```
## 选项
### A
```
csharp
// 以下代码的输出是
// ==
// "调用 DoSomethingAsync 之前"
// "等我一秒钟"
// "调用 DoSomethingAsync 之后"
//
Console
.
WriteLine
(
"调用 DoSomethingAsync 之前"
);
Task
task
=
DoSomethingAsync
();
Console
.
WriteLine
(
"调用 DoSomethingAsync 之后"
);
await
task
;
async
Task
DoSomethingAsync
(){
Task
.
Delay
(
10000
);
Console
.
WriteLine
(
"等我一秒钟"
);
}
```
### B
```
csharp
// 以下代码的输出是
// ==
// "调用 DoSomethingAsync 之前"
// "调用 DoSomethingAsync 之后"
//
Console
.
WriteLine
(
"调用 DoSomethingAsync 之前"
);
Task
task
=
DoSomethingAsync
();
Console
.
WriteLine
(
"调用 DoSomethingAsync 之后"
);
async
Task
DoSomethingAsync
(){
Thread
.
Sleep
(
1000
);
Console
.
WriteLine
(
"等我一秒钟"
);
}
```
### C
```
csharp
// 以下代码的输出是
// ==
// "调用 DoSomethingAsync 之前"
// "调用 DoSomethingAsync 之后"
// "等我一秒钟"
//
Console
.
WriteLine
(
"调用 DoSomethingAsync 之前"
);
Task
task
=
DoSomethingAsync
();
Console
.
WriteLine
(
"调用 DoSomethingAsync 之后"
);
await
task
;
async
Task
DoSomethingAsync
(){
Task
delay
=
Task
.
Delay
(
1000
);
await
delay
;
Console
.
WriteLine
(
"等我一秒钟"
);
}
```
\ No newline at end of file
data/1..NET初阶/3.C#特性/3.C#5.0特性/CallerInfo.json
0 → 100644
浏览文件 @
0e67cb44
{
"type"
:
"code_options"
,
"author"
:
"huanhuilong"
,
"source"
:
"CallerInfo.md"
,
"notebook_enable"
:
false
,
"exercise_id"
:
"1248fc45c96849e383437b49ac38d405"
}
\ No newline at end of file
data/1..NET初阶/3.C#特性/3.C#5.0特性/CallerInfo.md
0 → 100644
浏览文件 @
0e67cb44
# 函数调用者信息
通常我们会封装一个函数用来打印日志,但是在在日志函数里,会丢失掉这个日志函数在哪个地方被调用的信息,缺失这个信息会导致诊断问题的时候不方便直接找到出问题的位置。
下面的代码,会在编译期把函数调用位置的信息记录下来,在运行时打印出来。
```
csharp
using
System.Runtime.CompilerServices
;
TraceMessage
(
"HelloWorld"
);
void
TraceMessage
(
string
message
,
[
CallerMemberName
]
string
memberName
=
""
,
[
CallerFilePath
]
string
sourceFilePath
=
""
,
[
CallerLineNumber
]
int
sourceLineNumber
=
0
)
{
Console
.
WriteLine
(
"message: "
+
message
);
Console
.
WriteLine
(
"member name: "
+
memberName
);
Console
.
WriteLine
(
"source file path: "
+
sourceFilePath
);
Console
.
WriteLine
(
"source line number: "
+
sourceLineNumber
);
}
```
输出信息是:
```
bash
message: HelloWorld
member name: <Main>
$
source
file path: ...../Program.cs
source
line number: 3
```
以下说法错误的是?
## 答案
```
csharp
使用调用者信息属性,不需要引入
using
System.Runtime.CompilerServices
;
```
## 选项
### A
```
csharp
[
CallerMemberName
]
是函数参数的属性标记,这是
CSharp
特有的语法
```
### B
```
csharp
//
// (1)和(2)输出的 source line number 不同
//
using
System.Runtime.CompilerServices
;
Test
();
void
Test
(){
TraceMessage
(
"HelloWorld"
);
//(1)
TraceMessage
(
"HelloWorld"
);
//(2)
}
void
TraceMessage
(
string
message
,
[
CallerMemberName
]
string
memberName
=
""
,
[
CallerFilePath
]
string
sourceFilePath
=
""
,
[
CallerLineNumber
]
int
sourceLineNumber
=
0
)
{
Console
.
WriteLine
(
"message: "
+
message
);
Console
.
WriteLine
(
"member name: "
+
memberName
);
Console
.
WriteLine
(
"source file path: "
+
sourceFilePath
);
Console
.
WriteLine
(
"source line number: "
+
sourceLineNumber
);
}
```
### C
```
csharp
//
// (1)和(2)输出的 source file path 和 member name 相同
//
using
System.Runtime.CompilerServices
;
Test
();
void
Test
(){
TraceMessage
(
"HelloWorld"
);
//(1)
TraceMessage
(
"HelloWorld"
);
//(2)
}
void
TraceMessage
(
string
message
,
[
CallerMemberName
]
string
memberName
=
""
,
[
CallerFilePath
]
string
sourceFilePath
=
""
,
[
CallerLineNumber
]
int
sourceLineNumber
=
0
)
{
Console
.
WriteLine
(
"message: "
+
message
);
Console
.
WriteLine
(
"member name: "
+
memberName
);
Console
.
WriteLine
(
"source file path: "
+
sourceFilePath
);
Console
.
WriteLine
(
"source line number: "
+
sourceLineNumber
);
}
```
\ No newline at end of file
data/1..NET初阶/3.C#特性/3.C#5.0特性/config.json
浏览文件 @
0e67cb44
{
"node_id"
:
"csharp-730d385761c64702b710308c91271c9c"
,
"keywords"
:
[
"case支持表达式"
,
"带参数的泛型构造函数"
,
"扩展属性"
,
"支持null类型运算"
,
"绑定运算符,:=:"
"async"
,
"await"
,
"caller information"
],
"children"
:
[],
"export"
:
[],
"export"
:
[
"AsyncAwait.json"
,
"CallerInfo.json"
],
"keywords_must"
:
[],
"keywords_forbid"
:
[]
}
\ No newline at end of file
data/1..NET初阶/3.C#特性/3.C#5.0特性/sample/Program.cs
0 → 100644
浏览文件 @
0e67cb44
using
System.Runtime.CompilerServices
;
Test
();
void
Test
(){
TraceMessage
(
"HelloWorld"
);
//(1)
TraceMessage
(
"HelloWorld"
);
//(2)
}
void
TraceMessage
(
string
message
,
[
CallerMemberName
]
string
memberName
=
""
,
[
CallerFilePath
]
string
sourceFilePath
=
""
,
[
CallerLineNumber
]
int
sourceLineNumber
=
0
)
{
Console
.
WriteLine
(
"message: "
+
message
);
Console
.
WriteLine
(
"member name: "
+
memberName
);
Console
.
WriteLine
(
"source file path: "
+
sourceFilePath
);
Console
.
WriteLine
(
"source line number: "
+
sourceLineNumber
);
}
// 同步
// Console.WriteLine("调用 DoSomethingSync 之前");
// DoSomethingSync();
// Console.WriteLine("调用 DoSomethingSync 之后");
// void DoSomethingSync(){
// Thread.Sleep(1000);
// Console.WriteLine("等我一秒钟");
// }
// 异步
// Console.WriteLine("调用 DoSomethingAsync 之前");
// Task task = DoSomethingAsync();
// Console.WriteLine("调用 DoSomethingAsync 之后");
// await task;
// async Task DoSomethingAsync(){
// Task delay = Task.Delay(1000);
// await delay;
// Console.WriteLine("等我一秒钟");
// }
data/1..NET初阶/3.C#特性/3.C#5.0特性/sample/sample.csproj
0 → 100644
浏览文件 @
0e67cb44
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
data/tree.json
浏览文件 @
0e67cb44
...
...
@@ -210,10 +210,10 @@
"C#4.0特性"
:
{
"node_id"
:
"csharp-d4650354f5f5498e9969fd98bbb40323"
,
"keywords"
:
[
"
协变和逆变
"
,
"
dynamic
"
,
"命名参数"
,
"可选参数"
,
"
动态查找
"
"
协变和逆变
"
],
"children"
:
[],
"keywords_must"
:
[],
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录