c# 一些警告的處理方法

尋找無名的特質發表於2022-04-27

在使用.Net 6開發程式時,發現多了很多新的警告型別。這裡總結一下處理方法。

CS8618 在退出建構函式時,不可為 null 的 屬性“Name”必須包含非 null 值

經常遇到的有CS8618警告:如果定義屬性可能為空時,在編譯時會報這個警告,比如下面的程式碼:

    public class Play
    {
        public string Name { get; set; }

        public Play()
        {

        }

警告如下:
CS8618 在退出建構函式時,不可為 null 的 屬性“Name”必須包含非 null 值。請考慮將 屬性 宣告為可以為 null。
處理辦法是將屬性宣告為可以為空:

    public class Play
    {
        public string? Name { get; set; }

        public Play()
        {

        }
    }

或者,給屬性設定初始值:

    public class Play
    {
        public string Name { get; set; } = "";

        public Play()
        {

        }
    }

但遇到下面的情況,這兩種辦法就不能用了:


public class GameSocialDbContext : DbContext
{
  public DbSet<GameMessage> GameMessages { get; set; }
  public DbSet<Player> Players { get; set; }
  public GameSocialDbContext(DbContextOptions<GameSocialDbContext> options) : base(options)
  {
  }

}

這種情況下,可以將屬性設定default!來避免警告:

        public DbSet<Game> Games { get; set; } = default!;
        public DbSet<Player> Players { get; set; } = default!;

CS1998 此非同步方法缺少await運算子

這種情況通常出現在過載或者實現某個非同步方法時,沒有可呼叫的非同步函式。比如下面的方法:

        public async Task RemoveAsync(Player player)
        {
            Players.Remove(player);
        }

這種情況下,可以在退出前增加 await Task.CompletedTask;來避免警告。
如果需要返回值,比如:

        public async Task<List<Player>> GetAllAsync()
        {
            return colTemp.AsQueryable<Player>().ToList();
        }

這時,可以使用await Task.FromResult()作為返回值:

        public async Task<List<Player>> GetAllAsync()
        {
            return await Task.FromResult(colTemp.AsQueryable<Player>().ToList());
        }

CS8602 解引用可能出現空引用

如果採用as進行轉換,可能出現這個警告:

 await (handler as IEventHandler).HandleEvent(data);

可以改為強制轉換:

 await ((IEventHandler)handler).HandleEvent(data);

也可以使用!操作符:

 await (handler as IEventHandler)!.HandleEvent(data);

還可以在呼叫前判斷是否為空,如果為空,丟擲異常。

CS8603 可能返回null引用

這種警告多出現在過濾時,比如:

        public async Task<Player> GetPlayerByNameAsync(string name)
        {
            return await gameDbContext.Players
                .Include(p => p.SentFriendRequests)
                .Include(p => p.ReceievedFriendRequests).FirstOrDefaultAsync(p => p.UserName == name);
        }

由於FirstOrDefault可能返回空值,所以會出現警告。可以改為使用First:

        public async Task<Player> GetPlayerByNameAsync(string name)
        {
            return await gameDbContext.Players
                .Include(p => p.SentFriendRequests)
                .Include(p => p.ReceievedFriendRequests).FirstAsync(p => p.UserName == name);
        }

或者允許返回值為空:

        public async Task<Player?> GetPlayerByNameAsync(string name)
        {
            return await gameDbContext.Players
                .Include(p => p.SentFriendRequests)
                .Include(p => p.ReceievedFriendRequests).FirstOrDefaultAsync(p => p.UserName == name);
        }

最後需要說明的是,警告是為了提示程式可能的潛在問題,消除警告時,需要結合具體情況確定使用哪種方式,不要為了去掉警告忽略潛在的問題。

相關文章