ฉันสงสัยว่ามีใครสามารถอธิบายได้ว่าอะไรFunc<int, string>
คืออะไรและใช้อย่างไรกับตัวอย่างที่ชัดเจน
ฉันสงสัยว่ามีใครสามารถอธิบายได้ว่าอะไรFunc<int, string>
คืออะไรและใช้อย่างไรกับตัวอย่างที่ชัดเจน
คำตอบ:
คุณคุ้นเคยกับผู้ได้รับมอบหมายโดยทั่วไปหรือไม่? ฉันมีหน้าเกี่ยวกับผู้รับมอบสิทธิ์และเหตุการณ์ที่อาจช่วยได้หากไม่มีแม้ว่าจะมุ่งเน้นไปที่การอธิบายความแตกต่างระหว่างทั้งสอง
Func<T, TResult>
เป็นเพียงผู้รับมอบสิทธิ์ทั่วไป - ค้นหาความหมายในสถานการณ์เฉพาะใด ๆ โดยการแทนที่พารามิเตอร์ type ( T
และTResult
) ด้วยอาร์กิวเมนต์ประเภทที่เกี่ยวข้อง( int
และstring
) ในการประกาศ ฉันยังเปลี่ยนชื่อเพื่อหลีกเลี่ยงความสับสน:
string ExpandedFunc(int x)
กล่าวอีกนัยหนึ่งFunc<int, string>
คือ delegate ซึ่งแสดงถึงฟังก์ชันที่รับint
อาร์กิวเมนต์และส่งคืน a string
.
Func<T, TResult>
มักใช้ใน LINQ ทั้งสำหรับการคาดการณ์และเพรดิเคต (ในกรณีหลังTResult
คือเสมอbool
) ตัวอย่างเช่นคุณสามารถใช้ a Func<int, string>
เพื่อแสดงลำดับของจำนวนเต็มเป็นลำดับของสตริง โดยปกติแล้วนิพจน์ Lambdaจะใช้ใน LINQ เพื่อสร้างผู้รับมอบสิทธิ์ที่เกี่ยวข้อง:
Func<int, string> projection = x => "Value=" + x;
int[] values = { 3, 7, 10 };
var strings = values.Select(projection);
foreach (string s in strings)
{
Console.WriteLine(s);
}
ผลลัพธ์:
Value=3
Value=7
Value=10
Func<int, string>
กิน ints และผลตอบแทนสตริง ดังนั้นสิ่งที่กิน ints และส่งคืนสตริง? แล้วนี่ ...
public string IntAsString( int i )
{
return i.ToString();
}
ที่นั่นฉันเพิ่งสร้างฟังก์ชันที่กิน ints และส่งคืนสตริง ฉันจะใช้มันอย่างไร?
var lst = new List<int>() { 1, 2, 3, 4, 5 };
string str = String.Empty;
foreach( int i in lst )
{
str += IntAsString(i);
}
// str will be "12345"
ฉันรู้ว่าไม่เซ็กซี่มาก แต่นั่นเป็นแนวคิดง่ายๆที่มีกลเม็ดมากมาย ตอนนี้เรามาใช้ Func แทน
Func<int, string> fnc = IntAsString;
foreach (int i in lst)
{
str += fnc(i);
}
// str will be "1234512345" assuming we have same str as before
แทนที่จะเรียก IntAsString กับสมาชิกแต่ละคนฉันสร้างการอ้างอิงถึงมันที่เรียกว่า fnc (การอ้างอิงถึงวิธีการเหล่านี้เรียกว่าตัวแทน ) และใช้สิ่งนั้นแทน (จำไว้ว่า fnc กิน ints และส่งคืนสตริง)
ตัวอย่างเช่นนี้ไม่ได้เซ็กซี่มาก แต่ตันของสิ่งที่ฉลาดคุณจะเห็นอยู่บนพื้นฐานของความคิดที่เรียบง่ายของฟังก์ชั่นที่ได้รับมอบหมายและวิธีการขยาย
หนึ่งในไพรเมอร์ที่ดีที่สุดสำหรับเรื่องนี้ผมเคยเห็นเป็นที่นี่ เขามีตัวอย่างจริงมากขึ้น :)
มันเป็นผู้รับมอบสิทธิ์ที่จะใช้อย่างใดอย่างหนึ่งเป็นพารามิเตอร์และส่งกลับค่าของชนิดint
string
นี่คือตัวอย่างการใช้งาน:
using System;
class Program
{
static void Main()
{
Func<Int32, String> func = bar;
// now I have a delegate which
// I can invoke or pass to other
// methods.
func(1);
}
static String bar(Int32 value)
{
return value.ToString();
}
}
Func<int, string>
ยอมรับพารามิเตอร์ค่า int และส่งกลับค่าสตริง นี่คือตัวอย่างที่ไม่จำเป็นต้องใช้วิธีการสนับสนุนเพิ่มเติม
Func<int, string> GetDogMessage = dogAge =>
{
if (dogAge < 3) return "You have a puppy!";
if (dogAge < 7) return "Strong adult dog!";
return "Age is catching up with the dog!";
};
string youngDogMessage = GetDogMessage(2);
หมายเหตุ: ประเภทอ็อบเจ็กต์สุดท้ายใน Func (เช่น "สตริง" ในตัวอย่างนี้) คือประเภทการส่งคืนฟังก์ชัน (กล่าวคือไม่ จำกัด เฉพาะไพรเมทีฟ แต่อ็อบเจ็กต์ใด ๆ ) ดังนั้นFunc<int, bool, float>
ยอมรับพารามิเตอร์ค่า int และ bool และส่งกลับค่าลอย
Func<int, bool, float> WorthlessFunc = (intValue, boolValue) =>
{
if(intValue > 100 && boolValue) return 100;
return 1;
};
float willReturn1 = WorthlessFunc(21, false);
float willReturn100 = WorthlessFunc(1000, true);
HTH