1.說說顯示實現介面和隱式實現介面的區別。 2.說說file訪問修飾的作用。 3.說說什麼是原始字元串。 4.C#10 中struct有什麼改進? 5.說說C#10中Lambda表達式的新特點。 6.說說對於泛型特性的理解。 7.說說在ASP.NET Core7中,依賴註入中的方法註入需要註意什麼? ...
1.說說顯示實現介面和隱式實現介面的區別。
2.說說file訪問修飾的作用。
3.說說什麼是原始字元串。
4.C#10 中struct有什麼改進?
5.說說C#10中Lambda表達式的新特點。
6.說說對於泛型特性的理解。
7.說說在ASP.NET Core7中,依賴註入中的方法註入需要註意什麼?
8.說說ASP.NET Core7 限流中間件。
9.說說Record關鍵字的用法
10.說說 Minimal API的特點,和普通API有什麼區別?
1.說說顯示實現介面和隱式實現介面的區別。
隱式介面實現: 如果類或者結構要實現的是單個介面,可以使用隱式實現。
顯式介面實現: 如果類或者結構繼承了多個介面,那麼介面中相同名稱成員就要顯式實現。顯示實現是
通過使用介面的完全限定名來實現介面成員的。
使用顯式介面成員執行體通常有兩個目的:
1、顯式介面成員執行體不能通過類的實例進行訪問,這就 可以從公有介面中把介面的實現部分單
獨分離開。如果一個類只在內部使用該介面,而類的使用者不會直接使用到該介面,這種顯式介面成員
執行體就可以起到作用。
2、 顯式介面成員執行體避免了介面成員之間因為同名而發生混淆。如果一個類希望對名稱和返回類型
相同的介面成員採用不同的實現方式,這就必須要使用到顯式介面成員執行體。 如果沒有顯式介面成員
執行體,那麼對於名稱和返回類型不同的介面成員,類也無法進行實現。
ex:
//約定介面
interface ISkill
{
void Flying();
}
//隱式實現ISkill介面
public class Bird: ISkill
{
public void Flying()
{
}
}
//第一種調用方式
Bird bird = new Bird();
bird.Flying();
//第二種調用方式
ISkill secondBrid = new Bird();
secondBrid.Flying();
//用類和介面都可以調用Flying方法
//約定兩個介面
interface InterfaceA
{
void Say();
}
interface InterfaceB
{
void Say();
}
//繼承
class Person:InterfaceA, InterfaceB
{
void InterfaceA.Say()
{
Console.WriteLine("helloA");
}
void InterfaceB.Say()
{
Console.WriteLine("helloB");
}
}
//訪問形式
class Program
{
static void Main(string[] args)
{
InterfaceA p = new Person();
p.Say();
InterfaceB p2 = new Person();
p2.Say();
}
}
// 顯示實現只能通過對應的介面訪問對應的介面內的方法。用實現類去訪問時訪問不到的。
2.說說file訪問修飾的作用。
.NET7到來時,C#11中添加了file訪問修飾符。就是文件的意思,file是只能用來定義類型的訪問修飾 符,不能定義類型中的類成員,即使嵌套類也不可以。file是用來定義使用範圍最小的類型訪問修飾符, 只限於在當前文件中,其他類型的成員內訪問。file基本的使用場景是,當需要一個類型時,但又不想這個類型的使用範圍延伸到外部,所以就在當 前.cs文件定義一個file訪問修飾符的類型,僅限於當前文件中的類型成員內部封裝並訪問。
ex:
public class Product {
public string ? Name {
get;
set;
}
public decimal PurchasePrice {
get;
set;
}
public void PrintSalesProduct() {
var salesPrice = new SalesPrice {
RetailPrice = PurchasePrice * 1.5 m, WholesalePrice = PurchasePrice * 1.2 m
};
Console.WriteLine($ "Name:{Name},{salesPrice}");
}
}
file record SalesPrice {
public decimal RetailPrice {
get;
set;
}
public decimal WholesalePrice {
get;
set;
}
}
3.說說什麼是原始字元串。
C# 11 引入了原始字元串特性,允許用戶利用原始字元串在代碼中插入大量的無需轉移的文本,方便開發者在代碼中以字元串的方式塞入代碼文本等。原始字元串需要被至少三個 " 包裹,例如 """ 和 """"" 等等,前後的引號數量要相等。
另外,原始字元串的縮進由後面引號的位置來確定
例如:
此時 str 是:帶有換行符的字元串
{
string str = """
hello
world
""";
Console.WriteLine(str);
}
此時 str 是:帶有換行符,且第二行有空格的字元串
{
var str = """"
hello
world
"""";
Console.WriteLine(str);
}
可以直接定義JSON格式
{
//可以直接定義JSON格式
var json = """"
{
"a": 1,
"b": {
"c": "hello",
"d": "world"
},
"c": [1, 2, 3, 4, 5]
}
"""";
Console.WriteLine(json);
object obj= Newtonsoft.Json.JsonConvert.DeserializeObject<object>(json);
Hashtable tb = Newtonsoft.Json.JsonConvert.DeserializeObject<Hashtable>
(json);
}
可以直接定義JSON格式
{
int age= 37;
string? jsonResult= $$"""
{
"Id":123,
"Name":"Richard",
"Age":"{{age}}"
}
""";
}
4. C#10 中struct有什麼改進?
主要在於支持了無參數構造函數的改進,在C# 10之前,約束了不能有無參數的構造函數,現在在C#10 方法了這一約束;public struct Teaach
{
public Teaach(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
5.說說C#10中Lambda表達式的新特點
在之前的版本中我們是需要顯式聲明委托類型,如上述被註釋的代碼,在 C# 10 就可以直接使用 var 來聲明由編譯器去推斷委托的類型// Func<int> func = () => 1;
var func = () => 1;
// Func<string> func2 = ()=>"Hello";
var func2 = () => "Hello";
我們可以在指定輸入參數類型的時候,可以設置 ref / out / int 來表示一個值類型的引用傳遞,示例如
下
var refFunc = (ref int x) => { x++; };
var outFunc = (out int x) => { x = -1; };
var inFunc = (in int x) => { };
var num = 1;
refFunc(ref num);
Console.WriteLine(num);
outFunc(out num);
Console.WriteLine(num);
C# 10 的委托可以指定返回類型,如下:
// return type
var lambdaWithReturnValue0 = int? () => null;
// return type and input type
var lambdaWithReturnValue1 = int? (string s)
=> string.IsNullOrEmpty(s) ? 1 : null;
// Func<bool, object>
var choose = object (bool b) => b ? 1 : "two";
對於能夠推斷出類型的方法,我們也可以使用 var 來聲明委托,示例如下
// Action<string> func3 = LocalMethod;
var func3 = LocalMethod;
void LocalMethod(string a)
{
Console.WriteLine(a);
}
var checkFunc = string.IsNullOrEmpty;
var read = Console.Read;
Action<string> write = Console.Write;
現在我們可以在 Lambda 表達式中指定 Attribute
var parse3 =[Description("Lambda attribute")](string s) => int.Parse(s);
var choose3 =[Description("Lambda attribute1")]object (bool b) => b ? 1 : "two";
6.說說對於泛型特性的理解。
泛型:不確定的類型,聲明時不確定類型,調用時確定類型。可以支持一個類、方法、委托、介面等 類 支持不同類型的需求;那麼對於泛型的支持;C# 10 推廣了特性,使得特性可以用泛型,如下例:
public sealed class SomeAttribute<T> : Attribute
{
}
在使用的時候:
[SomeAttribute<int>]
class A { }
[SomeAttribute<string>]
class B { }
7.說說在ASP.NET Core7中,依賴註入中的方法註入需要註意什麼?
在MinimalAPI 或者是控制器中的方法中,如果需要支持註入,因為註入的對象和方法的參數是寫在一起 的。會出現系統無法識別這裡寫的參數究竟是要註入,還是調用方傳入的參數。那麼如果明確那個參數 是要通過註入(也就是說通過IOC容器來創建),就需要給這個參數標記一個特性【FromServices】,指 定當前這個參數是來自於IOC容器,也就是註入進來的。8.說說ASP.NET Core7 限流中間件。
實操如下:安裝.NET 7.0 SDK
通過nuget包安裝Microsoft.AspNetCore.RateLimiting
創建.NET7網站應用,註冊中間件
可以根據不同資源不同限制併發數,/api首碼的資源租約數2,等待隊列長度為2,其他預設租約數1,隊列長度1。
app.UseRateLimiter(new RateLimiterOptions()
{
// 觸發限流的響應碼
DefaultRejectionStatusCode = 500,
OnRejected = async (ctx, rateLimitLease) =>
{
// 觸發限流回調處理
},
Limiter = PartitionedRateLimiter.Create<HttpContext, string>(resource =>
{
if (resource.Request.Path.StartsWithSegments("/api"))
{
return RateLimitPartition.CreateConcurrencyLimiter("WebApiLimiter", _ => new ConcurrencyLimiterOptions(2,QueueProcessingOrder.NewestFirst, 2));
}
else
{
return RateLimitPartition.CreateConcurrencyLimiter("DefaultLimiter",
_ => new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));
}
})
});
9. 說說Record關鍵字的用法
可以用來簡單聲明一個類:record People
{
public string Name { get; init; }
public int Age { get; init; }
}
上面是聲明一個類
下麵的聲明也是聲明一個類,和上面的一樣;不需要使用大括弧來執行屬性;
record People2(string Name, int Age);
這裡的示例,用 record 聲明瞭兩個 實體,第二個 實體 聲明的時候使用了簡化的寫法,record
People2(string Name, int Age); 這樣的聲明意味著,構造方法有兩個參數,分別是 string Name 和 int
Age,並對應著兩個屬性,屬性的聲明方式和 People 一樣 public string Name { get; init; } 都是一個
get 一個 init,對於 record 支持一個 with 表達式,來修改某幾個屬性的值,這對於有很多屬性都相同的
場景來說是及其方便的;