ผู้แทน Func ที่ไม่มีประเภทการส่งคืน


561

ผู้รับมอบสิทธิ์ Func ทั้งหมดคืนค่า ผู้ได้รับมอบหมาย. NET ที่สามารถใช้กับวิธีที่คืนค่าเป็นโมฆะคืออะไร

คำตอบ:


759

ตัวแทน Func ทั้งหมดส่งคืนบางสิ่ง ผู้แทนการดำเนินการทั้งหมดส่งคืนโมฆะ

Func<TResult> จะไม่มีข้อโต้แย้งและส่งกลับ TResult:

public delegate TResult Func<TResult>()

Action<T> รับอาร์กิวเมนต์หนึ่งตัวและไม่ส่งคืนค่า:

public delegate void Action<T>(T obj)

Action เป็นตัวแทนที่ง่ายที่สุด 'เปลือย':

public delegate void Action()

นอกจากนี้ยังมีFunc<TArg1, TResult>และAction<TArg1, TArg2>(และอื่น ๆ ถึง 16 อาร์กิวเมนต์) สิ่งเหล่านี้ (ยกเว้นAction<T>) เป็นสิ่งใหม่สำหรับ. NET 3.5 (กำหนดไว้ใน System.Core)


11
FYI เวอร์ชันถัดไปของไลบรารีคลาสพื้นฐานจะมีประเภท Func และ Action ที่สนับสนุนพารามิเตอร์ทางการมากกว่าสี่รายการ ฉันจำไม่ได้ว่าพวกมันใหญ่แค่ไหน
Eric Lippert

88
ใน. NET 4.0 พวกเขาไปได้ถึง 8 พารามิเตอร์ ถ้าพวกเขารักษามันไว้ในเวอร์ชั่นถัดไปมันจะขึ้นไปสิบเอ็ด !! 11 !!!
Michiel van Oosterhout

9
ที่จริงแล้วดูเหมือนว่าพวกเขาจะสูงถึง 16 ใน 4.0
Tustin2121

7
1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, ... สิ่งนี้บ่งชี้อย่างชัดเจนว่าคอมไพเลอร์จะต้องสามารถรับมือกับการขัดแย้งกับฟังก์ชั่นได้มากกว่าที่จะเกิดขึ้นในอนาคต !
Chris Morgan

6
ที่จริงแล้ว Tustin2121 นั้นถูกต้องพวกมันมีพารามิเตอร์มากถึง 16 พารามิเตอร์ (บวกกับชนิดที่ส่งคืนในกรณีของFunc<,,, ... ,>. NET 4.0) แต่มีการกำหนด "ประเภท" แปดชุดสุดท้ายในแต่ละชุดSystem.Core.dllไม่ใช่ในmscorlib.dllเหตุผลนั้นจะเป็นเหตุผล ทำไม michielvoo ไม่เห็นพวกเขา อย่างไรก็ตามไม่มีการเพิ่ม Funcs หรือ Actions ใน .NET เวอร์ชัน 4.5 และ 4.5.1 อีกต่อไป ลำดับนี้จะกลายเป็นA170836หรือA170875หรือไม่ คอยติดตาม.
Jeppe Stig Nielsen

83

... ไม่รับอาร์กิวเมนต์และมีประเภทการคืนเป็นโมฆะ?

ฉันเชื่อว่าActionเป็นวิธีแก้ปัญหานี้


47

ผู้รับมอบสิทธิ์ Func ทั้งหมดใช้พารามิเตอร์อย่างน้อยหนึ่งพารามิเตอร์

ที่ไม่เป็นความจริง. พวกเขาทั้งหมดใช้อาร์กิวเมนต์อย่างน้อยหนึ่งประเภท แต่อาร์กิวเมนต์นั้นเป็นตัวกำหนดประเภทการส่งคืน

ดังนั้นจึงFunc<T>ไม่ยอมรับพารามิเตอร์และส่งคืนค่า ใช้ActionหรือAction<T>เมื่อคุณไม่ต้องการคืนค่า


27

ลองSystem.Func<T>และSystem.Action


1
ฉันไม่คิดว่า 0 arg และอะไรที่มีอยู่ใน. Net 2.0 แม้ว่า
46430 Brian

1
มันแปลก: Func ไม่มีอยู่ใน. Net 2.0 แม้ว่า Predicate และ Action จะทำเช่นไร
Joel Coehoorn

2
สำหรับ. NET 2.0 ใช้ผู้รับมอบสิทธิ์ MethodInvoker
เทรเวอร์เอลเลียต

.NET 2 ยังมี (หรือมี) ประเภทผู้ร่วมประชุมซึ่งเป็นเหมือนในภายหลังConverter<TInput, TOutput> Func<T, TResult>มันถูกใช้ในList<>.ConvertAllวิธีการซึ่งคาดว่าองค์ประกอบในทุกList<>บนวัตถุอื่นและวางไว้ทั้งหมด "ค่าฟังก์ชั่น" List<>ในใหม่ (หลังจากนั้นมักจะใช้ Linq Selectสำหรับเรื่องนั้น)
Jeppe Stig Nielsen

0

ในบางครั้งคุณจะต้องเขียนผู้รับมอบสิทธิ์สำหรับการจัดการเหตุการณ์ซึ่งในกรณีนี้คุณสามารถใช้ประโยชน์จากการSystem.EvenHandler<T>ที่ยอมรับอาร์กิวเมนต์ชนิดโดยนัยobjectนอกเหนือไปจากพารามิเตอร์ตัวที่สองที่ควรได้รับจากEventArgsนอกเหนือไปจากพารามิเตอร์ตัวที่สองที่ควรจะเป็นผลมาจากผู้จัดกิจกรรมจะกลับมาvoid

ฉันพบว่ามีประโยชน์นี้เป็นการส่วนตัวระหว่างการทดสอบเพื่อสร้างการติดต่อกลับครั้งเดียวในเนื้อหาของฟังก์ชัน


0

... ไม่รับอาร์กิวเมนต์และมีประเภทการคืนเป็นโมฆะ?

หากคุณกำลังเขียนเพื่อSystem.Windows.Formsคุณยังสามารถใช้:

public delegate void MethodInvoker()

0

วิธีที่ง่ายมากในการเรียกใช้รูทีนย่อย return และ non value return กำลังใช้FuncและActionตามลำดับ (โปรดดูhttps://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx )

ลองตัวอย่างนี้

using System;

public class Program
{
    private Func<string,string> FunctionPTR = null;  
    private Func<string,string, string> FunctionPTR1 = null;  
    private Action<object> ProcedurePTR = null; 



    private string Display(string message)  
    {  
        Console.WriteLine(message);  
        return null;  
    }  

    private string Display(string message1,string message2)  
    {  
        Console.WriteLine(message1);  
        Console.WriteLine(message2);  
        return null;  
    }  

    public void ObjectProcess(object param)
    {
        if (param == null)
        {
            throw new ArgumentNullException("Parameter is null or missing");
        }
        else 
        {
            Console.WriteLine("Object is valid");
        }
    }


    public void Main(string[] args)  
    {  
        FunctionPTR = Display;  
        FunctionPTR1= Display;  
        ProcedurePTR = ObjectProcess;
        FunctionPTR("Welcome to function pointer sample.");  
        FunctionPTR1("Welcome","This is function pointer sample");   
        ProcedurePTR(new object());
    }  
}

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