Googling เป็นเพียงคีย์เวิร์ด แต่ฉันพบโค้ดบางตัวที่ระบุว่า
MyVariable = default(MyObject);
และฉันสงสัยว่ามันหมายถึงอะไร
Googling เป็นเพียงคีย์เวิร์ด แต่ฉันพบโค้ดบางตัวที่ระบุว่า
MyVariable = default(MyObject);
และฉันสงสัยว่ามันหมายถึงอะไร
คำตอบ:
nullNullable<T>จะส่งกลับค่าเริ่มต้นเป็นศูนย์Nullable<T>จะส่งคืนค่าว่าง (pseudo-null) (อันที่จริงนี่เป็นคำสั่งซ้ำของสัญลักษณ์แสดงหัวข้อย่อยแรก แต่ควรทำให้ชัดเจน)การใช้งานที่ใหญ่ที่สุดdefault(T)คือในยาชื่อสามัญและสิ่งต่างๆเช่นTry...รูปแบบ:
bool TryGetValue(out T value) {
if(NoDataIsAvailable) {
value = default(T); // because I have to set it to *something*
return false;
}
value = GetData();
return true;
}
ในขณะที่มันเกิดขึ้นฉันยังใช้มันในการสร้างรหัสซึ่งมันเป็นความเจ็บปวดในการเริ่มต้นฟิลด์ / ตัวแปร - แต่ถ้าคุณรู้ประเภท:
bool someField = default(bool);
int someOtherField = default(int)
global::My.Namespace.SomeType another = default(global::My.Namespace.SomeType);
defaultได้
int foo = default(int);เหมือนเดิมint foo;? เช่นไม่ได้กำหนดค่าเริ่มต้น ints เริ่มต้นให้มีค่าเดียวกับdefault(int)?
default(...); ชาวบ้านไม่มีค่าเริ่มต้น (แม้ว่าในทางเทคนิค.locals initใน IL หมายความว่าค่าเริ่มต้นจะเป็นศูนย์อีกครั้ง แต่คุณต้องใช้กลไกที่ไม่ปลอดภัยในการสังเกต)
defaultคำหลักจะส่งกลับnullสำหรับประเภทการอ้างอิงและzeroสำหรับประเภทค่าตัวเลข
สำหรับstructs มันจะส่งคืนสมาชิกแต่ละตัวของโครงสร้างที่เริ่มต้นเป็นศูนย์หรือว่างขึ้นอยู่กับว่าเป็นค่าหรือชนิดการอ้างอิง
Simple Sample code :<br>
class Foo
{
public string Bar { get; set; }
}
struct Bar
{
public int FooBar { get; set; }
public Foo BarFoo { get; set; }
}
public class AddPrinterConnection
{
public static void Main()
{
int n = default(int);
Foo f = default(Foo);
Bar b = default(Bar);
Console.WriteLine(n);
if (f == null) Console.WriteLine("f is null");
Console.WriteLine("b.FooBar = {0}",b.FooBar);
if (b.BarFoo == null) Console.WriteLine("b.BarFoo is null");
}
}
เอาท์พุท:
0
f is null
b.FooBar = 0
b.BarFoo is null
ค่าเริ่มต้นของMyObject. ดูคำหลักเริ่มต้นในรหัสทั่วไป (คู่มือการเขียนโปรแกรม C #) (MSDN):
ในคลาสและวิธีการทั่วไปปัญหาหนึ่งที่เกิดขึ้นคือการกำหนดค่าเริ่มต้นให้กับประเภท T ที่กำหนดพารามิเตอร์เมื่อคุณไม่ทราบสิ่งต่อไปนี้ล่วงหน้า:
- ไม่ว่า T จะเป็นประเภทอ้างอิงหรือประเภทค่า
- ถ้า T เป็นประเภทค่าไม่ว่าจะเป็นค่าตัวเลขหรือโครงสร้าง
กำหนดตัวแปร t ของชนิดที่กำหนดพารามิเตอร์ T คำสั่ง t = null จะใช้ได้ก็ต่อเมื่อ T เป็นประเภทอ้างอิงและ t = 0 จะใช้ได้เฉพาะกับประเภทค่าตัวเลขเท่านั้น แต่ไม่สามารถใช้กับโครงสร้างได้ วิธีแก้ปัญหาคือการใช้คีย์เวิร์ดเริ่มต้นซึ่งจะคืนค่า null สำหรับประเภทการอ้างอิงและศูนย์สำหรับประเภทค่าตัวเลข สำหรับโครงสร้างจะส่งคืนสมาชิกแต่ละคนของโครงสร้างที่เริ่มต้นเป็นศูนย์หรือว่างขึ้นอยู่กับว่าเป็นค่าหรือชนิดการอ้างอิง ตัวอย่างต่อไปนี้จากคลาส GenericList แสดงวิธีใช้คีย์เวิร์ดเริ่มต้น สำหรับข้อมูลเพิ่มเติมโปรดดูภาพรวม Generics
public class GenericList<T>
{
private class Node
{
//...
public Node Next;
public T Data;
}
private Node head;
//...
public T GetNext()
{
T temp = default(T);
Node current = head;
if (current != null)
{
temp = current.Data;
current = current.Next;
}
return temp;
}
}
ระบุค่าดีฟอลต์ของพารามิเตอร์ type ค่านี้จะเป็นค่าว่างสำหรับชนิดอ้างอิงและศูนย์สำหรับชนิดค่า
defaultผลตอบแทนที่คำว่า "เริ่มต้น" หรือ "ว่างเปล่า" ความคุ้มค่าตัวแปรของชนิดที่มีการร้องขอ
เหมาะสำหรับทุกสภาพการอ้างอิง (กำหนดด้วยclass, delegateฯลฯ ) nullนี้เป็น สำหรับประเภทค่า (กำหนดด้วยstruct, enumฯลฯ ) มันเป็นมูลค่าทั้งหมด zeroes (ตัวอย่างเช่นint 0, DateTime 0001-01-01 00:00:00ฯลฯ )
ส่วนใหญ่จะใช้กับรหัสทั่วไปที่ใช้ได้กับทั้งการอ้างอิงและประเภทค่าเนื่องจากคุณไม่สามารถกำหนดnullให้กับตัวแปรประเภทค่าได้
มันจะตั้งค่าเริ่มต้นของออบเจ็กต์เป็นตัวแปร: null สำหรับชนิดอ้างอิงและ 0 สำหรับชนิดค่า
บางทีนี่อาจช่วยคุณได้:
using System;
using System.Collections.Generic;
namespace Wrox.ProCSharp.Generics
{
public class DocumentManager < T >
{
private readonly Queue < T > documentQueue = new Queue < T > ();
public void AddDocument(T doc)
{
lock (this)
{
documentQueue.Enqueue(doc);
}
}
public bool IsDocumentAvailable
{
get { return documentQueue.Count > 0; }
}
}
}
ไม่สามารถกำหนด null ให้กับประเภททั่วไปได้ เหตุผลก็คือประเภททั่วไปยังสามารถสร้างอินสแตนซ์เป็นประเภทค่าได้และอนุญาตให้ใช้ null ได้เฉพาะกับประเภทการอ้างอิงเท่านั้น เพื่อหลีกเลี่ยงปัญหานี้คุณสามารถใช้คำหลักเริ่มต้น ด้วยคีย์เวิร์ดเริ่มต้น null ถูกกำหนดให้กับชนิดการอ้างอิงและ 0 ถูกกำหนดให้กับชนิดค่า
public T GetDocument()
{
T doc = default(T);
lock (this)
{
doc = documentQueue.Dequeue();
}
return doc;
}
คำหลักเริ่มต้นมีหลายความหมายขึ้นอยู่กับบริบทที่ใช้ คำสั่ง switch ใช้ค่าดีฟอลต์สำหรับการกำหนดเคสดีฟอลต์และด้วย generics ค่าดีฟอลต์จะใช้เพื่อเริ่มต้นชนิดทั่วไปเป็น null หรือ 0 ขึ้นอยู่กับว่าเป็นการอ้างอิงหรือประเภทค่า
เมื่อไม่มีการใช้ข้อ จำกัด เพื่อ จำกัด พารามิเตอร์ประเภททั่วไปให้เป็นประเภทอ้างอิงดังนั้นจึงสามารถส่งผ่านประเภทค่าเช่นโครงสร้างได้ ในกรณีดังกล่าวเปรียบเทียบพารามิเตอร์ชนิดเพื่อ null มักจะเป็นเท็จ , เพราะ struct สามารถเว้นว่าง แต่ไม่เคย null
รหัสผิด
public void TestChanges<T>(T inputValue)
try
{
if (inputValue==null)
return;
//operation on inputValue
}
catch
{
// ignore this.
}
}
แก้ไข
public void TestChanges<T>(T inputValue)
try
{
if (object.Equals(inputValue, default(T)) )
return;
//operation on inputValue
}
catch
{
// ignore this.
}
}
class Fooด้วยทรัพย์สินint n. ฉันสามารถ "เกิน"defaultเพื่อให้ตั้งค่าnเป็นพูด5แทนได้0หรือไม่