Aracılığıyla paylaş


Özel durumlar oluşturma ve fırlatma

Özel durumlar, programı çalıştırırken bir hata oluştuğunun gösterilmesi için kullanılır. Bir hatayı tanımlayan özel durum nesneleri oluşturulur ve fırlatılır. Çalışma zamanı daha sonra en uyumlu özel durum işleyicisini arar.

Programcılar, aşağıdaki koşullardan biri veya daha fazlası doğru olduğunda özel durumlar oluşturmalıdır:

  • yöntemi tanımlı işlevselliğini tamamlayamaz. Örneğin, bir yöntemin parametresi geçersiz bir değere sahipse:

    static void CopyObject(SampleClass original)
    {
        _ = original ?? throw new ArgumentException("Parameter cannot be null", nameof(original));
    }
    
  • Nesne durumuna bağlı olarak bir nesneye uygunsuz bir çağrı yapılır. Bir örnek, salt okunur bir dosyaya yazmaya çalışıyor olabilir. Nesne durumu bir işlem yapılmasına izin vermediğinde, InvalidOperationException veya bu sınıfın türevine dayalı bir nesne örneği fırlatın. Aşağıdaki kod, InvalidOperationException nesnesi oluşturan bir yöntem örneğidir:

    public class ProgramLog
    {
        FileStream logFile = null!;
        public void OpenLog(FileInfo fileName, FileMode mode) { }
    
        public void WriteLog()
        {
            if (!logFile.CanWrite)
            {
                throw new InvalidOperationException("Logfile cannot be read-only");
            }
            // Else write data to the log and return.
        }
    }
    
  • Bir yöntemin bağımsız değişkeni bir istisnaya neden olduğunda. Bu durumda, özgün özel durum yakalanmalı ve bir ArgumentException örneği oluşturulmalıdır. Özgün özel durum, ArgumentException oluşturucusunun InnerException parametresi olarak geçirilmelidir:

    static int GetValueFromArray(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (IndexOutOfRangeException e)
        {
            throw new ArgumentOutOfRangeException(
                "Parameter index is out of range.", e);
        }
    }
    

    Not

    Yukarıdaki örnekte InnerException özelliğinin nasıl kullanılacağı gösterilmektedir. Kasıtlı olarak basitleştirilmiştir. Uygulamada, kullanmadan önce bir dizinin aralıkta olup olmadığını denetlemeniz gerekir. Bir parametrenin üyesi, üyeyi çağırmadan önce tahmin edemeyeceğiniz bir özel durum oluşturursa bu özel durumu sarmalama tekniğini kullanabilirsiniz.

Özel durumlar, StackTraceadlı bir özelliği içerir. Bu dize, geçerli çağrı yığınındaki yöntemlerin adını ve her yöntem için özel durumun oluşturulduğu dosya adını ve satır numarasını içerir. StackTrace nesnesi, ortak dil çalışma zamanı (CLR) tarafından throw deyiminin noktasından itibaren otomatik olarak oluşturulur, bu nedenle istisnalar, yığın izlemesinin başlaması gereken noktadan atılmalıdır.

Tüm özel durumlar Messageadlı bir özellik içerir. Bu dize, özel durumun nedenini açıklayacak şekilde ayarlanmalıdır. Güvenliğe duyarlı bilgiler ileti metnine yerleştirilmemelidir. Message'nın yanı sıra, ArgumentException, istisnanın oluşmasına sebep olan bağımsız değişkenin adını belirten bir değere ayarlanması gereken ParamName adlı bir özellik içerir. Özellik ayarlayıcıda ParamNamevalueolarak ayarlanmalıdır.

Genel ve korumalı yöntemler, amaçlanan işlevlerini tamamlayamadıklarında istisnalar fırlatır. Atılan özel durum sınıfı, hata koşullarına uyan en özel durumdur. Bu özel durumlar sınıf işlevselliğinin bir parçası olarak belgelenmelidir ve özgün sınıf için türetilmiş sınıflar veya güncelleştirmeler geriye dönük uyumluluk için aynı davranışı korumalıdır.

Özel durumları fırlatırken kaçınılması gerekenler

Aşağıdaki liste, özel durumlar oluştururken kaçınılması gereken uygulamaları tanımlar:

  • Normal yürütmenin bir parçası olarak bir programın akışını değiştirmek için özel durumlar kullanmayın. Hata koşullarını raporlamak ve işlemek için özel durumları kullanın.
  • Özel durumlar, atılmak yerine dönüş değeri veya parametre olarak döndürülmemelidir.
  • Kendi kaynak kodunuzdan kasıtlı olarak System.Exception, System.SystemException, System.NullReferenceExceptionveya System.IndexOutOfRangeException atmayın.
  • Hata ayıklama modunda atılabilecek ancak dağıtım modunda atılamayacak istisnalar oluşturmayın. Geliştirme aşamasındaki çalışma zamanı hatalarını belirlemek için bunun yerine "Debug Assert" kullanın.

Görev döndüren yöntemlerde özel durumlar

async değiştiricisi ile bildirilen yöntemlerin özel durumlar söz konusu olduğunda dikkate alınması gereken bazı özel noktalar vardır. Bir async yönteminde oluşan özel durumlar, döndürülen görevde depolanır ve örneğin görev beklenene kadar ortaya çıkmaz. Depolanan özel durumlar hakkında daha fazla bilgi için bkz. zaman uyumsuz özel durumlar.

Öneririz ki, yöntemlerinizin zaman uyumsuz bölümlerine girmeden önce, bağımsız değişkenleri doğrulayın ve ArgumentException ve ArgumentNullExceptiongibi ilgili özel durumları fırlatın. Diğer bir ifadeyle, bu doğrulama özel durumlarının çalışma başlamadan önce zaman uyumlu bir şekilde ortaya çıkması gerekir. Aşağıdaki kod parçacığında, özel durumlar oluşturulursa ArgumentException özel durumlarının zaman uyumlu olarak ortaya çıktığı, InvalidOperationException ise döndürülen görevde depolandığı bir örnek gösterilmektedir.

// Non-async, task-returning method.
// Within this method (but outside of the local function),
// any thrown exceptions emerge synchronously.
public static Task<Toast> ToastBreadAsync(int slices, int toastTime)
{
    if (slices is < 1 or > 4)
    {
        throw new ArgumentException(
            "You must specify between 1 and 4 slices of bread.",
            nameof(slices));
    }

    if (toastTime < 1)
    {
        throw new ArgumentException(
            "Toast time is too short.", nameof(toastTime));
    }

    return ToastBreadAsyncCore(slices, toastTime);

    // Local async function.
    // Within this function, any thrown exceptions are stored in the task.
    static async Task<Toast> ToastBreadAsyncCore(int slices, int time)
    {
        for (int slice = 0; slice < slices; slice++)
        {
            Console.WriteLine("Putting a slice of bread in the toaster");
        }
        // Start toasting.
        await Task.Delay(time);

        if (time > 2_000)
        {
            throw new InvalidOperationException("The toaster is on fire!");
        }

        Console.WriteLine("Toast is ready!");

        return new Toast();
    }
}

Özel durum sınıflarını tanımlama

Programlar System ad alanında önceden tanımlanmış bir özel durum sınıfı oluşturabilir (daha önce belirtildiği durumlar dışında) veya Exceptiontüreterek kendi özel durum sınıflarını oluşturabilir. Türetilmiş sınıflar en az üç oluşturucu tanımlamalıdır: biri parametresiz oluşturucu, biri ileti özelliğini ayarlayan ve diğeri de hem Message hem de InnerException özelliklerini ayarlar. Örneğin:

[Serializable]
public class InvalidDepartmentException : Exception
{
    public InvalidDepartmentException() : base() { }
    public InvalidDepartmentException(string message) : base(message) { }
    public InvalidDepartmentException(string message, Exception inner) : base(message, inner) { }
}

Sağladıkları veriler özel durumu çözümlemek için yararlı olduğunda özel durum sınıfına yeni özellikler ekleyin. Türetilmiş özel durum sınıfına yeni özellikler eklenirse, eklenen bilgileri döndürmek için ToString() geçersiz kılınmalıdır.

C# dil belirtimi

Daha fazla bilgi için bkz. Özel Durumlar ve throw deyimi, C# Dil Belirtimi. Dil belirtimi, C# söz dizimi ve kullanımı için kesin kaynaktır.

Ayrıca bkz.