จะลบองค์ประกอบว่างทั้งหมดภายในรายการทั่วไปได้อย่างไร?


112

มีวิธีการเริ่มต้นที่กำหนดไว้ใน. Net สำหรับ C # เพื่อลบองค์ประกอบทั้งหมดภายในรายการซึ่งเป็นnull?

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};

สมมติว่าพารามิเตอร์บางตัวคือnull; ฉันไม่สามารถทราบล่วงหน้าและต้องการลบออกจากรายการของฉันเพื่อให้มีเฉพาะพารามิเตอร์ที่ไม่เป็นโมฆะ

คำตอบ:


225

คุณอาจต้องการสิ่งต่อไปนี้

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};
parameterList.RemoveAll(item => item == null);

4
ใช่นี่ก็เหมือนกับคำตอบของฉัน แต่ใช้ไวยากรณ์แลมบ์ดา C # 3 ที่ใหม่กว่า
Mark Bell

@ มาร์ค: ฉันเห็นวินาทีที่โพสต์และผู้ชายมันอยู่ใกล้ (32, 33 และ 34) ;)
Lance

1
ใช่ ... คำตอบของคุณใช้งานได้ดีแม้ในเวอร์ชันเก่าดังนั้น +1 มีฮ่า! ; Þ
Lance

43

ฉันไม่รู้วิธีการใด ๆ ในตัว แต่คุณสามารถใช้ linq:

parameterList = parameterList.Where(x => x != null).ToList();

5
สิ่งนี้ควรหลีกเลี่ยงหากparameterListเป็นรายการอยู่แล้วเนื่องจากจะสร้างสำเนาใหม่โดยไม่จำเป็น ในกรณีนั้นให้ใช้RemoveAllวิธีการตามที่ผู้อื่นแนะนำ
นิค

นี่อาจเป็นตัวเลือกที่ดีที่สุดหากคอลเล็กชันเป็นArrayไฟล์.
Andrew

25

วิธี RemoveAll ควรทำเคล็ดลับ:

parameterList.RemoveAll(delegate (object o) { return o == null; });

ทำไมไม่ใช้แลมด้า?
Mike de Klerk

12
นี่คือคำตอบสี่ขวบ ตอนนั้น C # 3 ค่อนข้างใหม่และฉันยังคงใช้ C # 2 วันต่อวัน ไวยากรณ์แลมบ์ดาเป็นวิธีที่จะไป อย่างไรก็ตามนี่ยังคงเป็นคำตอบที่ใช้ได้ดังนั้นฉันจึงทิ้งไว้ที่นี่สำหรับใครก็ตามที่ไม่สามารถใช้ไวยากรณ์ที่ใหม่กว่าได้ (ไม่ว่าด้วยเหตุผลใดก็ตาม)
Mark Bell

2
ฉันไม่รู้ว่าไวยากรณ์แลมบ์ดามาในภายหลัง ขอบคุณสำหรับคำอธิบาย! ไม่ต้องสงสัยเลยว่าใช้ได้
Mike de Klerk

8

วิธีOfType()นี้จะข้ามค่า null:

List<EmailParameterClass> parameterList =
    new List<EmailParameterClass>{param1, param2, param3...};

IList<EmailParameterClass> parameterList_notnull = 
    parameterList.OfType<EmailParameterClass>();

ในทางหนึ่งนี่เป็นแนวทางที่ดี แต่ก็สร้างความประหลาดใจให้กับนักพัฒนาที่คิดว่าOfTypeเลือกวัตถุบางประเภทโดยไม่คิดว่าจะไม่รวมnullค่า ... ดังนั้นฉันจึงเบื่อหน่ายเล็กน้อยที่จะแนะนำสิ่งนี้ เป็นรหัสของฉันเอง

@ BjörnAliGöranssonเห็นด้วย เป็นวิธีแก้ปัญหาที่น่าสนใจ แต่ไม่ได้ "อ่าน" อย่างชัดเจน การใช้. RemoveAll ด้วยแลมบ์ดายังคงเก็บทุกอย่างไว้ในบรรทัดเดียวในขณะที่ทำให้เห็นได้ชัดว่าผู้พัฒนาที่เขียนมันพยายามบรรลุอะไร อย่างไรก็ตามสิ่งนี้อาจมีประโยชน์หากมีประโยชน์ด้านความเร็วที่คุ้มค่า
MattD


2

ง่ายและไม่ต้องใช้ LINQ:

while (parameterList.Remove(null)) {};

วิธีนี้อยู่ในListชั้นเรียนถัดจากRemoveAllดังนั้นฉันขอแนะนำวิธีนี้เพื่อความชัดเจน หากประสิทธิภาพเป็นสิ่งสำคัญคุณสามารถใช้แนวทางนี้ได้ (แม้ว่าฉันจะลบวงเล็บออกและอาจเพิ่มความคิดเห็นสำหรับนักพัฒนาที่ไม่รู้จัก)
Andrew

1
@Andrew: ตาม MSDN RemoveAll ไม่ใช้ค่าว่าง ฉันคิดว่าฉันได้ทดสอบสิ่งนั้นด้วย แม้ว่าความคิดเห็นจะสมเหตุสมผล
Tobias Knauss

1
RemoveAllได้รับPredicateดังนั้นคุณควรใช้RemoveAll(x => x == null)ตามที่เห็นในคำตอบที่ยอมรับและ Mark Bell
แอนดรู

1

มีอีกทางเลือกหนึ่งที่เรียบง่ายและสง่างาม:

parameters.OfType<EmailParameterClass>();

การดำเนินการนี้จะลบองค์ประกอบทั้งหมดที่ไม่ใช่ประเภทEmailParameterClassซึ่งจะกรององค์ประกอบประเภทใด ๆ ออกไปอย่างnullชัดเจน

นี่คือการทดสอบ:

class Test { }
class Program
{
    static void Main(string[] args)
    {
        var list = new List<Test>();
        list.Add(null);
        Console.WriteLine(list.OfType<Test>().Count());// 0
        list.Add(new Test());
        Console.WriteLine(list.OfType<Test>().Count());// 1
        Test test = null;
        list.Add(test);
        Console.WriteLine(list.OfType<Test>().Count());// 1
        Console.ReadKey();
    }
}

จะได้ผลไหม จะไม่เป็นการอ้างอิงองค์ประกอบที่ยังคงเป็นประเภทEmailParameterClassและมีค่าเท่ากับnull?
derHugo

มันจะแน่นอนและฉันเพิ่มผู้ทดสอบเพื่อความบันเทิงของคุณ
Ryan Naccarato
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.