C# Uyarı dalgaları
C# derleyicisinin her sürümünde yeni uyarılar ve hatalar ortaya çıkarılabilir. Mevcut kodda yeni uyarılar bildirilebildiğinde, bu uyarılar uyarı dalgası olarak adlandırılan bir kabul etme sistemi altında kullanıma sunulmuştur. Kabul etme sistemi, mevcut kodda etkinleştirmek için eylem gerçekleştirmeden yeni uyarılar görmemeniz gerektiği anlamına gelir. Uyarı dalgaları proje dosyanızdaki AnalysisLevel öğesi kullanılarak etkinleştirilir. Belirtildiğinde <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
, etkin uyarı dalgası uyarıları hata oluşturur. C# 9'da uyarı dalgası 5 tanılaması eklendi. C# 10'da uyarı dalgası 6 tanılaması eklendi. C# 11'de uyarı dalgası 7 tanılaması eklendi. C# 12'de uyarı dalgası 8 tanılaması eklendi.
CS9123 - Zaman uyumsuz yöntemde yerel adresin veya parametrenin alınması bir GC deliği oluşturabilir.
Uyarı dalgası 8
İşleç &
, zaman uyumsuz yöntemlerdeki parametrelerde veya yerel değişkenlerde kullanılmamalıdır.
Aşağıdaki kod CS9123 oluşturur:
public static async Task LogValue()
{
int x = 1;
unsafe {
int* y = &x;
Console.WriteLine(*y);
}
await Task.Delay(1000);
}
C# 13'le başlayarak bu kod bir derleyici hatası oluşturur.
CS8981 - Tür adı yalnızca küçük harfli ascii karakterler içerir.
Uyarı dalgası 7
C# için eklenen tüm yeni anahtar sözcüklerin tümü küçük harf ASCII karakterleri olacaktır. Bu uyarı, türlerinizin hiçbirinin gelecekteki anahtar sözcüklerle çakışmamasını sağlar. Aşağıdaki kod CS8981 üretir:
public class lowercasename
{
}
Türü büyük harf karakteri, basamak veya alt çizgi gibi en az bir küçük harf olmayan ASCII karakteri içerecek şekilde yeniden adlandırarak bu uyarıyı giderebilirsiniz.
CS8826 - Kısmi yöntem bildirimlerinin imza farklılıkları vardır.
Uyarı dalgası 6
Bu uyarı, kısmi yöntem imzaları arasındaki farkları raporlamadaki bazı tutarsızlıkları düzeltir. Kısmi yöntem imzaları farklı CLR imzaları oluşturduğunda derleyici her zaman bir hata bildirdi. Şimdi, imzalar bozulmadan farklı C# olduğunda derleyici CS8826'yı bildirir. Aşağıdaki kısmi sınıfı göz önünde bulundurun:
public partial class PartialType
{
public partial void M1(int x);
public partial T M2<T>(string s) where T : struct;
public partial void M3(string s);
public partial void M4(object o);
public partial void M5(dynamic o);
public partial void M6(string? s);
}
Aşağıdaki kısmi sınıf uygulaması birkaç CS8626 örneği oluşturur:
public partial class PartialType
{
// Different parameter names:
public partial void M1(int y) { }
// Different type parameter names:
public partial TResult M2<TResult>(string s) where TResult : struct => default;
// Relaxed nullability
public partial void M3(string? s) { }
// Mixing object and dynamic
public partial void M4(dynamic o) { }
// Mixing object and dynamic
public partial void M5(object o) { }
// Note: This generates CS8611 (nullability mismatch) not CS8826
public partial void M6(string s) { }
}
Not
Bir yöntemin uygulanması, diğer bildirim null atanabilir başvuru türlerini kabul ettiğinde null atanamaz bir başvuru türü kullanıyorsa, CS8826 yerine CS8611 oluşturulur.
Bu uyarıların herhangi bir örneğini düzeltmek için iki imzanın eşleştiğinden emin olun.
CS7023 - 'is' veya 'as' ifadesinde statik bir tür kullanılır.
Uyarı dalgası 5
Statik bir türün is
örneklerini oluşturamadığınız için ve as
ifadeleri her zaman statik bir tür için döndürülebilir false
. Aşağıdaki kod CS7023 oluşturur:
static class StaticClass
{
public static void Thing() { }
}
void M(object o)
{
// warning: cannot use a static type in 'is' or 'as'
if (o is StaticClass)
{
Console.WriteLine("Can't happen");
}
else
{
Console.WriteLine("o is not an instance of a static class");
}
}
Tür testi hiçbir zaman başarılı olamadığından derleyici bu uyarıyı bildirir. Bu uyarıyı düzeltmek için testi kaldırın ve yalnızca test başarılı olursa yürütülen tüm kodları kaldırın. Yukarıdaki örnekte yan else
tümcesi her zaman yürütülür. Bu yöntem gövdesini şu tek satırla değiştirebilirsiniz:
Console.WriteLine("o is not an instance of a static class");
CS8073 - İfadenin sonucu her zaman 'false' (veya 'true').
Uyarı dalgası 5
==
ve işleçleri bir türün null
struct
örneğini ile karşılaştırırken her zaman (veyatrue
) döndürür false
.!=
Aşağıdaki kodda bu uyarı gösterilmektedir. ve operator !=
tanımlayan operator ==
bir struct
olduğunu varsayalımS
:
class Program
{
public static void M(S s)
{
if (s == null) { } // CS8073: The result of the expression is always 'false'
if (s != null) { } // CS8073: The result of the expression is always 'true'
}
}
struct S
{
public static bool operator ==(S s1, S s2) => s1.Equals(s2);
public static bool operator !=(S s1, S s2) => !s1.Equals(s2);
public override bool Equals(object? other)
{
// Implementation elided
return false;
}
public override int GetHashCode() => 0;
// Other details elided...
}
Bu hatayı düzeltmek için nesne ise null
yürütülecek null denetimini ve kodu kaldırın.
CS8848 - 'kimden' işleci öncelik nedeniyle burada kullanılamaz. Ayraç kullanarak kesinleştirme yapın.
Uyarı dalgası 5
Aşağıdaki örneklerde bu uyarı gösterilmektedir. İşleçlerin önceliği nedeniyle ifade yanlış bağlanır.
bool b = true;
var source = new Src();
b = true;
source = new Src();
var a = b && from c in source select c;
Console.WriteLine(a);
var indexes = new Src2();
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
var range = array[0..from c in indexes select c];
Bu hatayı düzeltmek için sorgu ifadesinin çevresine parantez ekleyin:
bool b = true;
var source = new Src();
b = true;
source = new Src();
var a = b && (from c in source select c);
Console.WriteLine(a);
var indexes = new Src2();
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
var range = array[0..(from c in indexes select c)];
Üyeler tamamen atanmalıdır. Atanmamış değişkenin kullanımı (CS8880, CS8881, CS8882, CS8883, CS8884, CS8885, CS8886, CS8887)
Uyarı dalgası 5
Birkaç uyarı, içeri aktarılan derlemelerde bildirilen türler için struct
kesin atama analizini geliştirir. Bu yeni uyarıların tümü, içeri aktarılan derlemedeki bir yapı, aşağıdaki örnekte gösterildiği gibi başvuru türünde erişilemez bir alan (genellikle bir private
alan) içerdiğinde oluşturulur:
public struct Struct
{
private string data = String.Empty;
public Struct() { }
}
Aşağıdaki örneklerde, geliştirilmiş kesin atama analizinden oluşturulan uyarılar gösterilmektedir:
- CS8880: Denetim çağırana döndürülmeden önce otomatik uygulanan 'Property' özelliği tam olarak atanmalıdır.
- CS8881: Denetim çağırana döndürülmeden önce 'alan' alanı tamamen atanmalıdır.
- CS8882: Denetim geçerli yöntemi terk etmeden önce out parametresi 'parameter' atanmalıdır.
- CS8883: Muhtemelen atanmamış otomatik uygulanan 'Property' özelliğinin kullanımı.
- CS8884: Atanmamış olabilecek 'Alan' alanının kullanımı
- CS8885: 'this' nesnesi tüm alanları atanmadan önce kullanılamaz.
- CS8886: Atanmamış 'parameterName' çıkış parametresinin kullanımı.
- CS8887: Atanmamış 'variableName' yerel değişkeninin kullanımı
public struct DefiniteAssignmentWarnings
{
// CS8880
public Struct Property { get; }
// CS8881
private Struct field;
// CS8882
public void Method(out Struct s)
{
}
public DefiniteAssignmentWarnings(int dummy)
{
// CS8883
Struct v2 = Property;
// CS8884
Struct v3 = field;
// CS8885:
DefiniteAssignmentWarnings p2 = this;
}
public static void Method2(out Struct s1)
{
// CS8886
var s2 = s1;
s1 = default;
}
public static void UseLocalStruct()
{
Struct r1;
var r2 = r1;
}
}
İçeri aktarılan yapıyı başlatarak veya varsayılan değerine atayarak bu uyarılardan herhangi birini düzeltebilirsiniz:
public struct DefiniteAssignmentNoWarnings
{
// CS8880
public Struct Property { get; } = default;
// CS8881
private Struct field = default;
// CS8882
public void Method(out Struct s)
{
s = default;
}
public DefiniteAssignmentNoWarnings(int dummy)
{
// CS8883
Struct v2 = Property;
// CS8884
Struct v3 = field;
// CS8885:
DefiniteAssignmentNoWarnings p2 = this;
}
public static void Method2(out Struct s1)
{
// CS8886
s1 = default;
var s2 = s1;
}
public static void UseLocalStruct()
{
Struct r1 = default;
var r2 = r1;
}
}
CS8892 - Zaman uyumlu bir 'yöntem' giriş noktası bulunduğundan yöntem giriş noktası olarak kullanılmaz.
Uyarı dalgası 5
Bu uyarı, bir veya daha fazla zaman uyumlu giriş noktası dahil olmak üzere birden çok geçerli giriş noktanız olduğunda tüm zaman uyumsuz giriş noktası adaylarında oluşturulur.
Aşağıdaki örnek CS8892 oluşturur:
public static void Main()
{
RunProgram();
}
// CS8892
public static async Task Main(string[] args)
{
await RunProgramAsync();
}
Not
Derleyici her zaman zaman uyumlu giriş noktasını kullanır. Birden çok zaman uyumlu giriş noktası olması durumunda bir derleyici hatası alırsınız.
Bu uyarıyı düzeltmek için zaman uyumsuz giriş noktasını kaldırın veya yeniden adlandırın.
CS8897 - Statik türler parametre olarak kullanılamaz
Uyarı dalgası 5
Bir arabirimin üyeleri, türü statik sınıf olan parametreleri bildiremez. Aşağıdaki kod hem CS8897 hem de CS8898'i gösterir:
public static class Utilities
{
// elided
}
public interface IUtility
{
// CS8897
public void SetUtility(Utilities u);
// CS8898
public Utilities GetUtility();
}
Bu uyarıyı düzeltmek için parametre türünü değiştirin veya yöntemini kaldırın.
CS8898 - Statik türler dönüş türleri olarak kullanılamaz
Uyarı dalgası 5
Bir arabirimin üyeleri statik sınıf olan bir dönüş türü bildiremez. Aşağıdaki kod hem CS8897 hem de CS8898'i gösterir:
public static class Utilities
{
// elided
}
public interface IUtility
{
// CS8897
public void SetUtility(Utilities u);
// CS8898
public Utilities GetUtility();
}
Bu uyarıyı düzeltmek için dönüş türünü değiştirin veya yöntemini kaldırın.