在使用.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);
}
最後需要說明的是,警告是為了提示程式可能的潛在問題,消除警告時,需要結合具體情況確定使用哪種方式,不要為了去掉警告忽略潛在的問題。