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 nullstruct ö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 nullyü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.