Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Null yapılabilir başvuru türleri, null yapılabilir değer türlerinin değer türlerini tamamladığı gibi başvuru türlerini tamamlar. Türüne bir ekleyerek bir değişkeni ? null atanabilir başvuru türü olarak bildirirsiniz. Örneğin, string? null yapılabilir bir stringtemsil eder. Tasarım amacınızı daha net bir şekilde ifade etmek için bu yeni türleri kullanabilirsiniz: Bazı değişkenlerin her zaman bir değeri olmalıdır , bazıları ise değer eksik olabilir.
Bu eğitimde şunları öğreniyorsunuz:
- Tasarımlarınıza null değer atanabilir ve null değer atanamayan başvuru türlerini ekleyin
- Kodunuz genelinde null değer alabilen başvuru türü denetimlerini etkinleştirin.
- Derleyicinin bu tasarım kararlarını zorunlu kıldığı kod yazın.
- Kendi tasarımlarınızda null atanabilir referans özelliğini kullanın.
Önkoşullar
- En son .NET SDK
- Visual Studio Code düzenleyici
- C# Geliştirme Kiti
Bu öğreticide, Visual Studio veya .NET CLI dahil olmak üzere C# ve .NET hakkında bilgi sahibi olduğunuz varsayılır.
Null değer atanabilir başvuru türlerini tasarımlarınıza dahil edin
Bu öğreticide, anket çalıştırmayı modelleyen bir kitaplık oluşturacaksınız. Kod, gerçek dünya kavramlarını temsil etmek için hem null olabilen referans türlerini hem de null olamayan referans türlerini kullanır. Anket soruları hiçbir zaman boş olamaz. Yanıtlayan bir soruyu yanıtlamamayı tercih edebilir. Yanıtlar bu durumda null olabilir.
Bu örnek için yazdığınız kod bu amacı belirtir ve derleyici bu amacın yerine getirilmesini sağlar.
Uygulamayı oluştur ve null atanabilir referans türlerini etkinleştir
dotnet new consolekullanarak Visual Studio'da veya komut satırından yeni bir konsol uygulaması oluşturun. Uygulamayı NullableIntroductionolarak adlandırın. Uygulamayı oluşturduktan sonra, tüm projenin nullable ek açıklama bağlamı etkinleştirildiğinde derlenmesini belirtmeniz gerekir.
.csproj dosyasını açın ve Nullable öğesine bir PropertyGroup öğesi ekleyin. değerini enableolarak ayarlayın. C# 11 / .NET 7'nin öncesinde oluşturulan projelerde null atanabilir başvuru türleri özelliğini kabul etmeniz gerekir. Özellik açıldıktan sonra, mevcut başvuru değişkeni bildirimleri null atanamaz başvuru türlerine dönüşür. Bu karar, mevcut kodun doğru null denetimlere sahip olmamasıyla ilgili sorunları bulmaya yardımcı olsa da, özgün tasarım amacınızı doğru yansıtmayabilir:
<Nullable>enable</Nullable>
Uygulama türlerini tasarlama
Bu anket uygulaması şu sınıfların oluşturulmasını gerektirir:
- Soru listesini modelleyen bir sınıf.
- Anket için iletişim kuran kişilerin listesini modelleyen bir sınıf.
- Anketi dolduran bir kişinin yanıtlarını modelleyen bir sınıf.
Bu türler, hangi üyelerin gerekli olduğunu ve hangi üyelerin isteğe bağlı olduğunu ifade etmek için hem null atanabilir hem de null atanamaz başvuru türlerini kullanır. Null değer alabilen başvuru türleri, bu tasarım amacını açıkça iletir.
- Anketin parçası olan sorular hiçbir zaman null olamaz: Boş bir soru sormak mantıklı değildir.
- Yanıtlayanlar hiçbir zaman null olamaz. İletişim kurduğun kişileri, hatta katılmayı reddeden yanıtlayanları izlemek istiyorsunuz.
- Bir soruya verilen yanıt null olabilir. Yanıtlayanlar soruların bazılarını veya tümünü yanıtlamayı reddedebilir.
Değerlere izin veren null başvuru türlerine o kadar alışkın olabilirsiniz ki, null atanamayan örnekleri tanımlamak için diğer fırsatları kaçırabilirsiniz.
- Soru koleksiyonu null olmayan olmalıdır.
- Yanıtlayanların koleksiyonu null olamaz.
Kodu yazarken, başvurular için varsayılan olarak null olamayan bir başvuru türü kullanmanın, NullReferenceException gibi yaygın hatalara yol açmaktan kaçındığını görürsünüz. Bu öğreticiden alınacak derslerden biri, hangi değişkenlerin null olabileceğine veya olamayacağına karar vermenizdir. Dil, bu kararları ifade etmek için söz dizimi sağlamadı. Şimdi de var.
Oluşturduğunuz uygulama aşağıdaki adımları uygular:
- Anket oluşturur ve bu ankete sorular ekler.
- Anket için sahte rastgele bir yanıtlayan kümesi oluşturur.
- Tamamlanan anket boyutu hedef numaraya ulaşana kadar yanıtlayanlarla iletişime geçer.
- Anket yanıtlarıyla ilgili önemli istatistikleri yazar.
Nullable ve null değeri kabul etmeyen referans türleriyle anket oluşturun.
Yazdığınız ilk kod anketi oluşturur. Bir anket sorusunu ve anket çalıştırmasını modellemek için sınıflar yazarsınız. Anketinizde yanıtın biçimiyle ayırt edilen üç soru türü vardır: Evet/Hayır yanıtları, sayı yanıtları ve metin yanıtları.
public SurveyQuestion sınıfı oluşturma:
namespace NullableIntroduction
{
public class SurveyQuestion
{
}
}
Derleyici, her başvuru türü değişken bildirimini, null atanabilir ek açıklama bağlamındaki kod için null atanamaz başvuru türü olarak yorumlar. Aşağıdaki kodda gösterildiği gibi soru metninin özelliklerini ve soru türünü ekleyerek ilk uyarınızı görebilirsiniz:
namespace NullableIntroduction
{
public enum QuestionType
{
YesNo,
Number,
Text
}
public class SurveyQuestion
{
public string QuestionText { get; }
public QuestionType TypeOfQuestion { get; }
}
}
Başlatmadığınız QuestionText için, derleyici null atanamayan bir özelliğin başlatılmadığını belirten bir uyarı yayınlar. Tasarımınız soru metninin null olmayan olmasını gerektirdiğinden, bunu başlatmak için bir oluşturucu ve QuestionType değeri de eklersiniz. Tamamlanmış sınıf tanımı aşağıdaki koda benzer:
namespace NullableIntroduction;
public enum QuestionType
{
YesNo,
Number,
Text
}
public class SurveyQuestion
{
public string QuestionText { get; }
public QuestionType TypeOfQuestion { get; }
public SurveyQuestion(QuestionType typeOfQuestion, string text) =>
(TypeOfQuestion, QuestionText) = (typeOfQuestion, text);
}
Oluşturucunun eklenmesi uyarıyı kaldırır. Oluşturucu argümanı da null olmayan bir referans türüdür, bu yüzden derleyici herhangi bir uyarı vermez.
Ardından, publicadlı bir SurveyRun sınıfı oluşturun. Bu sınıf, aşağıdaki kodda gösterildiği gibi ankete soru eklemek için SurveyQuestion nesnelerinin ve yöntemlerinin listesini içerir:
using System.Collections.Generic;
namespace NullableIntroduction
{
public class SurveyRun
{
private List<SurveyQuestion> surveyQuestions = new List<SurveyQuestion>();
public void AddQuestion(QuestionType type, string question) =>
AddQuestion(new SurveyQuestion(type, question));
public void AddQuestion(SurveyQuestion surveyQuestion) => surveyQuestions.Add(surveyQuestion);
}
}
Daha önce olduğu gibi, liste nesnesini null olmayan bir değere başlatmanız gerekir veya derleyici bir uyarı verir. Derleyici, null atanamaz sözleşmenin uygulanmasına yardımcı olduğundan, AddQuestion ikinci aşırı yüklemesinde null kontrolü yoktur: Bu değişkeni null atanamaz olarak bildirdiniz. Derleyici olası null atamalar hakkında uyarsa da, çalışma zamanı null değerleri hala mümkündür. Genel API'ler için, istemci kodunda null atanabilir başvuru türleri etkinleştirilmediğinden veya kasıtlı olarak null geçirebileceğinden, null atanamayan başvuru türleri için bile bağımsız değişken doğrulaması eklemeyi göz önünde bulundurun.
Düzenleyicinizde Program.cs geçin ve Main içeriğini aşağıdaki kod satırlarıyla değiştirin:
var surveyRun = new SurveyRun();
surveyRun.AddQuestion(QuestionType.YesNo, "Has your code ever thrown a NullReferenceException?");
surveyRun.AddQuestion(new SurveyQuestion(QuestionType.Number, "How many times (to the nearest 100) has that happened?"));
surveyRun.AddQuestion(QuestionType.Text, "What is your favorite color?");
Projenin tamamı etkin null atanabilir açıklama bağlamında olduğundan, null atanmaz başvuru türü bekleyen herhangi bir yönteme null geçtiğinizde, uyarılar alırsınız.
Mainaşağıdaki satırı ekleyerek deneyin:
surveyRun.AddQuestion(QuestionType.Text, default);
Yanıtlayanlar oluşturma ve ankete yanıt alma
Ardından, ankete yanıt oluşturan kodu yazın. Bu işlem birkaç küçük görev içerir:
- Yanıtlayan nesneler oluşturan bir yöntem oluşturun. Bu nesneler anketi doldurması istenen kişileri temsil eder.
- Yanıtlayana soru sorma ve yanıt toplama ya da yanıtlayanın yanıt vermediğini belirtme simülasyonu yapmak için mantık oluşturun.
- Yeterli sayıda katılımcı anketi tamamlayana kadar tekrarlayın.
Anket yanıtlarını temsil etmek için bir sınıfa ihtiyacınız vardır, bu nedenle bunu şimdi ekleyin. Nullable desteğini etkinleştirin. Aşağıdaki kodda gösterildiği gibi bir Id özelliği ve bunu başlatan bir oluşturucu ekleyin:
namespace NullableIntroduction
{
public class SurveyResponse
{
public int Id { get; }
public SurveyResponse(int id) => Id = id;
}
}
Ardından, rastgele bir kimlik oluşturarak yeni katılımcılar oluşturmak için bir static yöntemi ekleyin:
private static readonly Random randomGenerator = new Random();
public static SurveyResponse GetRandomId() => new SurveyResponse(randomGenerator.Next());
Bu sınıfın temel sorumluluğu, anketteki sorulara bir katılımcının yanıtlarını oluşturmaktır. Bu sorumluluğun birkaç adımı vardır:
- Ankete katılmayı isteyin. Kişi onay vermezse, eksik (veya boş) bir yanıt döndürün.
- Her soruyu sorun ve yanıtı kaydedin. Her yanıt da eksik (veya null) olabilir.
SurveyResponse sınıfınıza aşağıdaki kodu ekleyin:
private Dictionary<int, string>? surveyResponses;
public bool AnswerSurvey(IEnumerable<SurveyQuestion> questions)
{
if (ConsentToSurvey())
{
surveyResponses = new Dictionary<int, string>();
int index = 0;
foreach (var question in questions)
{
var answer = GenerateAnswer(question);
if (answer != null)
{
surveyResponses.Add(index, answer);
}
index++;
}
}
return surveyResponses != null;
}
private bool ConsentToSurvey() => randomGenerator.Next(0, 2) == 1;
private string? GenerateAnswer(SurveyQuestion question)
{
switch (question.TypeOfQuestion)
{
case QuestionType.YesNo:
int n = randomGenerator.Next(-1, 2);
return (n == -1) ? default : (n == 0) ? "No" : "Yes";
case QuestionType.Number:
n = randomGenerator.Next(-30, 101);
return (n < 0) ? default : n.ToString();
case QuestionType.Text:
default:
switch (randomGenerator.Next(0, 5))
{
case 0:
return default;
case 1:
return "Red";
case 2:
return "Green";
case 3:
return "Blue";
}
return "Red. No, Green. Wait.. Blue... AAARGGGGGHHH!";
}
}
Anket yanıtlarının depolama alanı null olabileceğini belirten bir Dictionary<int, string>?değeridir. Tasarım amacınızı hem derleyiciye hem de kodunuzu daha sonra okuyan herkese bildirmek için yeni dil özelliğini kullanıyorsunuz. Eğer null değerini önce kontrol etmeden surveyResponses başvurusunu çözerseniz, bir derleyici uyarısı alırsınız. Derleyici değişkeninin AnswerSurvey önceki kodda null olmayan bir değere ayarlandığını belirleyebildiğinden surveyResponses yönteminde uyarı almazsınız.
Eksik yanıtlar için null kullanılması, null atanabilir başvuru türleriyle çalışmanın önemli bir noktasını vurgular: amacınız tüm null değerlerini programınızdan kaldırmak değildir. Bunun yerine, amacınız yazdığınız kodun tasarımınızın amacını ifade etmesini sağlamaktır. Eksik değerler, kodunuzda ifade etmek için gerekli bir kavramdır.
null değeri, bu eksik değerleri ifade etmenin net bir yoludur. Tüm null değerleri kaldırmaya çalışmak, bu eksik değerleri olmadan nullifade etmek için başka bir yol tanımlamaya neden olur.
Ardından, PerformSurvey sınıfında SurveyRun yöntemini yazmanız gerekir.
SurveyRun sınıfına aşağıdaki kodu ekleyin:
private List<SurveyResponse>? respondents;
public void PerformSurvey(int numberOfRespondents)
{
int respondentsConsenting = 0;
respondents = new List<SurveyResponse>();
while (respondentsConsenting < numberOfRespondents)
{
var respondent = SurveyResponse.GetRandomId();
if (respondent.AnswerSurvey(surveyQuestions))
respondentsConsenting++;
respondents.Add(respondent);
}
}
Burada da null olabilir bir List<SurveyResponse>? seçeneğiniz, yanıtın null olabileceğini gösterir. Bu, anketin henüz yanıtlayanlara verilmediğini gösterir. Yeterli onay gelene kadar yanıtlayanların eklendiğine dikkat edin.
Anketi çalıştırmanın son adımı, Main yönteminin sonunda anketi gerçekleştirmek için bir çağrı eklemektir:
surveyRun.PerformSurvey(50);
Anket yanıtlarını inceleme
Son adım anket sonuçlarını görüntülemektir. Yazdığınız sınıfların çoğuna kod eklersiniz. Bu kod, null atanabilir ve boş değer atanamayan başvuru türlerini ayırt etme değerini gösterir.
SurveyResponse sınıfına aşağıdaki iki ifade gövdeli üye ekleyerek başlayın:
public bool AnsweredSurvey => surveyResponses != null;
public string Answer(int index) => surveyResponses?.GetValueOrDefault(index) ?? "No answer";
surveyResponses null atanabilir bir başvuru türü olduğundan, başvuru çözümlemesi yapmadan önce null kontrolü gereklidir.
Answer yöntemi null atanamaz bir dize döndürür, bu nedenle null birleşim işlecini kullanarak eksik yanıt durumunu ele alacağız.
Ardından, SurveyRun sınıfına şu üç ifade gövdeli üyeyi ekleyin:
public IEnumerable<SurveyResponse> AllParticipants => (respondents ?? Enumerable.Empty<SurveyResponse>());
public ICollection<SurveyQuestion> Questions => surveyQuestions;
public SurveyQuestion GetQuestion(int index) => surveyQuestions[index];
AllParticipants üyesi, respondents değişkeninin null olabileceğini, ancak dönüş değerinin null olamaz olduğunu dikkate almalıdır. Bu ifadeyi ?? ve ardından gelen boş diziyi kaldırarak değiştirirseniz, derleyici yöntemin null döndürebileceği ve dönüş imzasının null atanamaz bir tür döndüreceği konusunda sizi uyarır.
Son olarak, Main yönteminin en altına aşağıdaki döngünün eklenmesini sağlar:
foreach (var participant in surveyRun.AllParticipants)
{
Console.WriteLine($"Participant: {participant.Id}:");
if (participant.AnsweredSurvey)
{
for (int i = 0; i < surveyRun.Questions.Count; i++)
{
var answer = participant.Answer(i);
Console.WriteLine($"\t{surveyRun.GetQuestion(i).QuestionText} : {answer}");
}
}
else
{
Console.WriteLine("\tNo responses");
}
}
Temel arabirimleri, tümünün null atanamaz başvuru türleri döndürmesi için tasarladığınız için bu kodda herhangi bir null denetime ihtiyacınız yoktur. Derleyicinin statik analizi, bu tasarım sözleşmelerine uyulmasını sağlamaya yardımcı olur.
Kodu al
Tamamlanmış öğreticinin kodunu csharp/NullableIntroduction klasöründeki örnekleri depomuzdan alabilirsiniz.
Null atanabilir ve null atanamayan başvuru türleri arasındaki tür bildirimlerini değiştirerek denemeler yapın. yanlışlıkla bir null'e başvurmadığınızdan emin olmak için bu işlemin nasıl farklı uyarılar ürettiğini görün.
Sonraki adımlar
Entity Framework kullanırken null atanabilir referans türünü kullanmayı öğrenin.