ฟังก์ชั่นแบบอินไลน์ใน C #?


276

คุณจะทำอย่างไร "ฟังก์ชั่นแบบอินไลน์" ใน C #? ฉันไม่คิดว่าฉันเข้าใจแนวคิดนี้ พวกเขาชอบวิธีที่ไม่ระบุชื่อหรือไม่? เช่นเดียวกับฟังก์ชั่นแลมบ์ดา?

หมายเหตุ : คำตอบเกือบทั้งหมดเกี่ยวข้องกับความสามารถในการทำงานของอินไลน์เช่น "การปรับให้เหมาะสมด้วยตนเองหรือคอมไพเลอร์ที่แทนที่ไซต์การเรียกใช้ฟังก์ชันด้วยเนื้อความของผู้เรียก" หากคุณสนใจฟังก์ชั่นนิรนาม (aka lambda)โปรดดูคำตอบของ @ jalfหรือทุกคนที่ 'แลมบ์ดา' พูดถึงอะไร? .


11
เป็นไปได้ในที่สุด - ดูคำตอบของฉัน
konrad.kruczynski

1
สำหรับสิ่งที่ใกล้เคียงก่อนคำถาม .NET 4.5 เห็นวิธีการกำหนดตัวแปรเป็นฟังก์ชั่นแลมบ์ดา ไม่ได้รวบรวมเป็น inline แต่เป็นการประกาศฟังก์ชันสั้น ๆ เช่นการประกาศแบบอินไลน์ ขึ้นอยู่กับสิ่งที่คุณพยายามทำโดยใช้อินไลน์
AppFzx

สำหรับคนที่อยากรู้อยากเห็นลองใช้ส่วนขยาย VSนี้
สาม

คำตอบ:


384

ในที่สุดใน. NET 4.5, CLR อนุญาตให้หนึ่งคำแนะนำ / แนะนำ1วิธีการอินไลน์โดยใช้MethodImplOptions.AggressiveInliningค่า นอกจากนี้ยังมีอยู่ในหีบของ Mono (มุ่งมั่นในวันนี้)

// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices; 

...

[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)

1 . ก่อนหน้านี้มีการใช้ "แรง" ที่นี่ เนื่องจากมีการโหวตไม่กี่ครั้งฉันจะพยายามอธิบายให้ชัดเจน ในความคิดเห็นและเอกสารThe method should be inlined if possible.โดยเฉพาะอย่างยิ่งเมื่อพิจารณาจากโมโน (ซึ่งเปิด) มีข้อ จำกัด ทางเทคนิคเฉพาะสำหรับการพิจารณาแบบอินไลน์หรือทั่วไปมากกว่าหนึ่ง (เช่นฟังก์ชั่นเสมือน) โดยรวมแล้วใช่นี่เป็นคำใบ้ของคอมไพเลอร์ แต่ฉันเดาว่าเป็นสิ่งที่ถูกถาม


17
+1 - อัปเดตคำตอบของคุณให้เฉพาะเจาะจงมากขึ้นเกี่ยวกับข้อกำหนดรุ่นของเฟรมเวิร์ก
M.Babcock

4
ก็ยังคงอาจจะไม่ได้เป็นแรงแบบอินไลน์ แต่เอาชนะความกระวนกระวายใจการวิเคราะห์พฤติกรรมอย่างแน่นอนเพียงพอในสถานการณ์ส่วนใหญ่
CodesInChaos

7
วิธีที่แตกต่างที่สามารถทำงานร่วมกับ. NET ทุกรุ่นได้คือการแบ่งวิธีที่มีขนาดใหญ่เกินไปเล็กน้อยออกเป็นสองวิธีหนึ่งวิธีที่เรียกอีกวิธีหนึ่งซึ่งไม่เกิน 32 ไบต์ของ IL ผลกระทบสุทธิจะเหมือนกับว่าต้นฉบับถูก inlined
Rick Sladkey

4
มันไม่ได้บังคับให้ "Inlining" เป็นเพียงแค่พยายามพูดคุยกับ JIT และบอกว่าโปรแกรมเมอร์ต้องการใช้ Inlining ที่นี่จริงๆ แต่ JIT มีคำพูดสุดท้าย ดังนั้น MSDN: วิธีการควรจะ inline ถ้าเป็นไปได้
Orel Eraki

11
จากการเปรียบเทียบคำแนะนำแบบอินไลน์ของ C ++ แม้กระทั่งตัวแปลเฉพาะเจาะจงก็ไม่ได้บังคับให้อินไลน์: ฟังก์ชั่นบางอย่างอาจไม่สามารถแทรกได้ ดังนั้นใช่พลัง "ไม่ค่อนข้าง" นี้เป็นเรื่องปกติ
Eamon Nerbonne

87

วิธีการแบบอินไลน์เป็นเพียงการเพิ่มประสิทธิภาพของคอมไพเลอร์ที่รหัสของฟังก์ชั่นจะถูกรีดเข้าไปในผู้โทร

ไม่มีกลไกที่จะทำสิ่งนี้ใน C # และพวกมันจะถูกใช้อย่าง จำกัด ในภาษาที่พวกเขาได้รับการสนับสนุน - ถ้าคุณไม่รู้ว่าทำไมพวกเขาถึงต้องใช้ที่ไหนสักแห่งพวกเขาก็ไม่ควร

แก้ไข: เพื่อชี้แจงมีเหตุผลสำคัญสองประการที่จำเป็นต้องใช้อย่าง จำกัด :

  1. มันง่ายที่จะสร้างไบนารีขนาดใหญ่โดยใช้อินไลน์ในกรณีที่ไม่จำเป็น
  2. คอมไพเลอร์มีแนวโน้มที่จะรู้ดีกว่าที่คุณทำเมื่อมีบางสิ่งที่ควรจะถูก inline จากมุมมองประสิทธิภาพ

เป็นการดีที่สุดที่จะปล่อยให้สิ่งต่าง ๆ อยู่ตามลำพังและให้คอมไพเลอร์ทำงานตามปกติจากนั้นทำโปรไฟล์และหาว่าอินไลน์เป็นทางออกที่ดีที่สุดสำหรับคุณหรือไม่ แน่นอนว่ามีบางสิ่งที่เข้าท่า (ผู้ดำเนินการทางคณิตศาสตร์โดยเฉพาะ) แต่การให้คอมไพเลอร์จัดการมันเป็นวิธีปฏิบัติที่ดีที่สุด


35
ปกติฉันคิดว่ามันก็โอเคที่คอมไพเลอร์จัดการอินไลน์ แต่มีบางสถานการณ์ที่ฉันต้องการแทนที่การตัดสินใจของคอมไพเลอร์และอินไลน์หรือไม่อินไลน์วิธี
mmmmmmmm

7
@Joel Coehoorn: นี่เป็นการปฏิบัติที่ไม่ดีเพราะมันจะทำลายการทำให้เป็นโมดูลและการป้องกันการเข้าถึง (คิดเกี่ยวกับวิธีการ inlined ในระดับที่เข้าถึงสมาชิกส่วนตัวและถูกเรียกจากจุดที่แตกต่างกันในรหัสที่!)
mmmmmmmm

9
@Poma นั่นเป็นเหตุผลที่แปลกที่จะใช้อินไลน์ ฉันสงสัยอย่างมากว่ามันจะพิสูจน์ว่ามีประสิทธิภาพ
Chris Shouts

56
ข้อโต้แย้งเกี่ยวกับคอมไพเลอร์ที่รู้ว่าดีที่สุดนั้นผิด มันไม่ได้อินไลน์วิธีใด ๆ ที่มากกว่า 32 IL, ระยะเวลา นี่เป็นเรื่องที่น่ากลัวสำหรับโครงการ (เช่นของฉันและของ Egor ด้านบน) ที่มีฮอตสปอตที่ระบุโดยผู้สร้างเราไม่สามารถทำอะไรได้เลย ไม่มีอะไรนั่นคือยกเว้นการตัดและวางโค้ดและอินไลน์ด้วยตนเอง นี่คือสถานะของกิจการที่น่ากลัวเมื่อคุณกำลังขับเคลื่อนการแสดงจริง ๆ
สว่าง

6
การฝังเป็นสิ่งที่ลึกซึ้งยิ่งกว่าที่ปรากฏ หน่วยความจำมีแคชที่เข้าถึงได้อย่างรวดเร็วและส่วนปัจจุบันของรหัสจะถูกเก็บไว้ในแคชเหล่านั้นเหมือนกับตัวแปร คำแนะนำในการโหลดบรรทัดแคชถัดไปคือแคชที่เสียไปและอาจมีค่าใช้จ่าย 10 เท่าหรือมากกว่านั้นสิ่งที่คำสั่งเดียวทำ ในที่สุดก็ต้องโหลดลงในแคช L2 ซึ่งมีราคาแพงกว่า ดังนั้นโค้ดป่องอาจทำให้พลาดแคชมากขึ้นซึ่งฟังก์ชั่นอินไลน์ที่อยู่ในบรรทัดแคช L1 เดียวกันตลอดเวลาอาจทำให้แคชหายไปน้อยลงและโค้ดอาจเร็วขึ้น ด้วย. Net มันซับซ้อนยิ่งขึ้น

56

อัปเดต:ตามคำตอบของ konrad.kruczynskiต่อไปนี้เป็นจริงสำหรับ. NET เวอร์ชั่นขึ้นไปและรวมถึง 4.0

คุณสามารถใช้คลาส MethodImplAttributeเพื่อป้องกันไม่ให้มีการinline ...

[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
    // ...
}

... แต่มีวิธีที่จะทำตรงข้ามและไม่มีการบังคับให้มีการ inlined


2
สนใจที่จะรู้ว่า แต่ทำไม heck ป้องกันวิธีการที่จะ inline? ฉันใช้เวลาจ้องมองที่จอภาพ แต่ฉันไม่สามารถหาเหตุผลได้ว่าทำไมการอินไลน์อาจทำอันตรายใด ๆ
Camilo Martin

3
หากคุณได้รับ call stack (เช่น NullReferenceException) และเห็นได้ชัดว่าไม่มีวิธีใดที่เมธอดด้านบนของสแต็กจะขว้างมัน แน่นอนว่าหนึ่งในสายอาจมี แต่อันไหน
dzendras

19
GetExecutingAssemblyและGetCallingAssemblyสามารถให้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับว่าวิธีการถูกแทรก บังคับให้เมธอดเป็นแบบไม่มี inline กำจัดความไม่แน่นอนใด ๆ
stusmith

1
@Downvoter: ถ้าคุณไม่เห็นด้วยกับสิ่งที่ฉันเขียนคุณควรโพสต์ความคิดเห็นที่อธิบายว่าทำไม ไม่เพียง แต่เป็นมารยาททั่วไปคุณยังไม่ประสบความสำเร็จมากนักด้วยการรวมคะแนนโหวต 20+ คำตอบ
BACON

2
หวังว่าฉันจะได้ +2 เพราะชื่อของคุณสมควรได้รับ +1: D
retrodrone

33

คุณกำลังผสมแนวคิดที่แยกกันสองอย่าง ฟังก์ชั่นอินไลน์เป็นคอมไพเลอร์ออปติไมซ์ที่ไม่มีผลกระทบต่อความหมาย ฟังก์ชั่นการทำงานเหมือนกันไม่ว่าจะเป็นแบบอินไลน์หรือไม่

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

ไม่มีคำหลักแบบอินไลน์ใน C # เนื่องจากเป็นการเพิ่มประสิทธิภาพที่สามารถทิ้งไว้กับคอมไพเลอร์โดยเฉพาะในภาษา JIT คอมไพเลอร์ JIT มีการเข้าถึงสถิติรันไทม์ซึ่งช่วยให้สามารถตัดสินใจว่าจะอินไลน์ได้อย่างมีประสิทธิภาพมากขึ้นกว่าที่คุณสามารถทำได้เมื่อเขียนโค้ด ฟังก์ชั่นจะมีการแทรกหากคอมไพเลอร์ตัดสินใจและไม่มีอะไรที่คุณสามารถทำได้ด้วยวิธีใดวิธีหนึ่ง :)


20
"ฟังก์ชั่นจะทำงานเหมือนกันไม่ว่าจะเป็นแบบอินไลน์หรือไม่ก็ตาม" มีบางกรณีที่ไม่ค่อยเกิดขึ้นซึ่งสิ่งนี้ไม่เป็นจริง: คือฟังก์ชันการบันทึกที่ต้องการทราบเกี่ยวกับการติดตามสแต็ก แต่ฉันไม่ต้องการบ่อนทำลายคำสั่งฐานของคุณมากเกินไป: โดยทั่วไปมันเป็นเรื่องจริง
Joel Coehoorn

"และไม่มีอะไรที่คุณสามารถทำได้ทั้งสองทาง" - ไม่จริง แม้ว่าเราจะไม่นับ "คำแนะนำที่รัดกุม" กับคอมไพเลอร์ว่าทำอะไรคุณก็สามารถป้องกันไม่ให้ฟังก์ชั่นอินไลน์ได้
BartoszKP

21

คุณหมายถึงฟังก์ชั่นแบบอินไลน์ในความหมาย C ++ หรือไม่ เนื้อหาของฟังก์ชั่นปกติใดที่จะถูกคัดลอกแบบอินไลน์โดยอัตโนมัติใน callsite? ผลสุดท้ายคือการที่ไม่มีการเรียกใช้ฟังก์ชันเกิดขึ้นจริงเมื่อเรียกใช้ฟังก์ชัน

ตัวอย่าง:

inline int Add(int left, int right) { return left + right; }

ถ้าเป็นเช่นนั้นไม่จะไม่มี C # ที่เทียบเท่ากับสิ่งนี้

หรือคุณหมายถึงฟังก์ชั่นที่ถูกประกาศในฟังก์ชั่นอื่นหรือไม่? ถ้าใช่ดังนั้น C # จะสนับสนุนสิ่งนี้ผ่านวิธีการไม่ระบุชื่อหรือการแสดงออกแลมบ์ดา

ตัวอย่าง:

static void Example() {
  Func<int,int,int> add = (x,y) => x + y;
  var result = add(4,6);  // 10
}

21

โคดี้พูดถูก แต่ฉันต้องการให้ตัวอย่างของฟังก์ชันอินไลน์

สมมติว่าคุณมีรหัสนี้:

private void OutputItem(string x)
{
    Console.WriteLine(x);

    //maybe encapsulate additional logic to decide 
    // whether to also write the message to Trace or a log file
}

public IList<string> BuildListAndOutput(IEnumerable<string> x)
{  // let's pretend IEnumerable<T>.ToList() doesn't exist for the moment
    IList<string> result = new List<string>();

    foreach(string y in x)
    {
        result.Add(y);
        OutputItem(y);
    }
    return result;
}

คอมไพเลอร์ Just-In-Time เพิ่มประสิทธิภาพสามารถเลือกที่จะเปลี่ยนรหัสเพื่อหลีกเลี่ยงการวางซ้ำ ๆ เรียกร้องให้ OutputItem () บนสแต็คเพื่อว่ามันจะเป็นเช่นถ้าคุณได้เขียนรหัสเช่นนี้แทน:

public IList<string> BuildListAndOutput(IEnumerable<string> x)
{
    IList<string> result = new List<string>();

    foreach(string y in x)
    {
        result.Add(y);

        // full OutputItem() implementation is placed here
        Console.WriteLine(y);   
    }

    return result;
}

ในกรณีนี้เราจะบอกว่าฟังก์ชั่น OutputItem () นั้นถูก inline โปรดทราบว่าอาจทำสิ่งนี้แม้ว่าจะเรียก OutputItem () จากที่อื่นเช่นกัน

แก้ไขเพื่อแสดงสถานการณ์มีแนวโน้มที่จะถูกแทรก


9
เพียงเพื่อชี้แจงว่า; มันคือ JIT ที่ทำอินไลน์ ไม่ใช่คอมไพเลอร์ C #
Marc Gravell

โปรดทราบว่าอย่างน้อยในขั้นต้น JIT จะ 'ชอบ' วิธีการคงที่แบบอินไลน์แม้จะข้ามขอบเขตการประกอบ ดังนั้นเทคนิคโรงเรียนเก่าสำหรับการเพิ่มประสิทธิภาพคือการทำเครื่องหมายวิธีการของคุณเป็นแบบคงที่ สิ่งนี้ได้ถูกชุมชนขมวดคิ้ว แต่จนถึงทุกวันนี้ฉันจะยังคงเลือกใช้วิธีการแบบอินไลน์ซึ่งเป็นแบบภายในไม่ใช่แบบโพลิมอร์ฟิคในธรรมชาติและโดยทั่วไปแล้วค่าใช้จ่ายน้อยกว่าในการดำเนินการ
Shaun Wilson

7

ใช่ความแตกต่างเพียงอย่างเดียวคือความจริงที่ว่ามันคืนค่า

การทำให้เข้าใจง่าย (ไม่ใช้นิพจน์):

List<T>.ForEach ทำการกระทำโดยไม่คาดหวังผลตอบแทน

ดังนั้นAction<T>ตัวแทนจะพอเพียง .. พูดว่า:

List<T>.ForEach(param => Console.WriteLine(param));

เหมือนกับการพูดว่า:

List<T>.ForEach(delegate(T param) { Console.WriteLine(param); });

ความแตกต่างคือประเภท param และ decleration ของตัวแทนได้รับการอนุมานจากการใช้งานและไม่จำเป็นต้องใช้เครื่องมือจัดฟันในวิธีการแบบอินไลน์อย่างง่าย

อยู่ที่ไหน

List<T>.Where รับฟังก์ชั่นโดยคาดหวังผลลัพธ์

ดังนั้นFunction<T, bool>จะคาดหวัง:

List<T>.Where(param => param.Value == SomeExpectedComparison);

ซึ่งเหมือนกับ:

List<T>.Where(delegate(T param) { return param.Value == SomeExpectedComparison; });

นอกจากนี้คุณยังสามารถประกาศวิธีการเหล่านี้แบบอินไลน์และกำหนดให้กับตัวแปร IE:

Action myAction = () => Console.WriteLine("I'm doing something Nifty!");

myAction();

หรือ

Function<object, string> myFunction = theObject => theObject.ToString();

string myString = myFunction(someObject);

ฉันหวังว่านี่จะช่วยได้.


2

มีบางครั้งที่ฉันต้องการบังคับให้โค้ดอยู่ในแนว

ตัวอย่างเช่นถ้าฉันมีกิจวัตรที่ซับซ้อนซึ่งมีการตัดสินใจจำนวนมากภายในบล็อกที่มีการวนซ้ำสูงและการตัดสินใจเหล่านั้นส่งผลให้มีการกระทำที่คล้ายกัน แต่แตกต่างกันเล็กน้อย ลองพิจารณาตัวอย่างเช่นตัวเรียงลำดับที่ซับซ้อน (ไม่ใช่ฐานข้อมูลขับเคลื่อน) ซึ่งตัวเรียงลำดับ algorythm เรียงลำดับองค์ประกอบตามจำนวนของเกณฑ์ที่ไม่เกี่ยวข้องที่แตกต่างกันเช่นหนึ่งอาจทำถ้าพวกเขาเรียงคำตามไวยากรณ์และความหมายของภาษาที่รวดเร็ว ระบบการรับรู้ ฉันมักจะเขียนฟังก์ชันผู้ช่วยเพื่อจัดการการกระทำเหล่านั้นเพื่อรักษาความสามารถในการอ่านและโมดุลของรหัสต้นฉบับ

ฉันรู้ว่าฟังก์ชั่นผู้ช่วยเหล่านั้นควรอยู่ในแนวเดียวกันเพราะนั่นเป็นวิธีที่รหัสจะถูกเขียนหากมนุษย์ไม่เคยเข้าใจ แน่นอนฉันต้องการรับประกันในกรณีนี้ว่าไม่มีฟังก์ชั่นการโทรโอเวอร์เฮด


2

คำแถลง "สิ่งที่ดีที่สุดที่จะทิ้งสิ่งเหล่านี้ไว้ตามลำพังและให้คอมไพเลอร์ทำงานได้ .. " (Cody Brocious) เป็นทับทิมสมบูรณ์ ฉันเขียนโปรแกรมเกมที่มีประสิทธิภาพสูงเป็นเวลา 20 ปีและฉันยังไม่ได้เจอคอมไพเลอร์ที่ 'ฉลาดพอที่จะรู้ว่าควรใช้โค้ดใดในฟังก์ชัน (ฟังก์ชั่น) หรือไม่ มันจะมีประโยชน์ที่จะมีคำสั่ง "inline" ใน c # ความจริงก็คือคอมไพเลอร์ไม่ได้มีข้อมูลทั้งหมดที่จำเป็นในการกำหนดฟังก์ชั่นที่ควรจะมีการ inline เสมอหรือไม่ไม่มีคำแนะนำ "inline" แน่นอนว่าถ้าฟังก์ชั่นนั้นมีขนาดเล็ก (accessor) มันอาจถูก inline อัตโนมัติ แต่ถ้ามันเป็นโค้ดไม่กี่บรรทัดล่ะ? เปล่าเลย, คอมไพเลอร์ไม่มีทางรู้, คุณไม่สามารถปล่อยให้มันถึงคอมไพเลอร์สำหรับรหัสที่ได้รับการปรับปรุง (เกินกว่าอัลกอริทึม)


3
"Nonesense ผู้เรียบเรียงไม่มีทางรู้" JITer ทำการรวบรวมข้อมูลการโทรแบบเรียลไทม์ ..
Brian Gordon

3
.NET JIT เป็นที่รู้จักกันดีในการเพิ่มประสิทธิภาพในขณะใช้งานดีกว่าสิ่งที่เป็นไปได้ด้วยการวิเคราะห์แบบคงที่ 2 รอบที่รวบรวมเวลา ส่วนที่ยากสำหรับนักเขียนโค้ด "old school" ที่ต้องเข้าใจก็คือ JIT ไม่ใช่ผู้รวบรวมซึ่งรับผิดชอบการสร้างโค้ดเนทีฟ JIT ไม่ใช่ผู้รวบรวมเป็นผู้รับผิดชอบวิธีการแบบอินไลน์
Shaun Wilson

1
เป็นไปได้สำหรับฉันที่จะรวบรวมรหัสที่คุณโทรเข้าโดยไม่มีซอร์สโค้ดของฉันและ JIT อาจเลือกที่จะโทรเข้าแบบอินไลน์ ปกติฉันจะเห็นด้วย แต่ฉันจะบอกว่าในฐานะมนุษย์คุณไม่สามารถใช้เครื่องมือได้อีกต่อไป
Shaun Wilson

1

ฉันรู้ว่าคำถามนี้เป็นเรื่องเกี่ยวกับ C # อย่างไรก็ตามคุณสามารถเขียนฟังก์ชั่นอินไลน์ใน. NET ด้วย F # ดู: การใช้ `inline 'ใน F #


ฉันถูกเปลี่ยนเส้นทางจากที่นี่: stackoverflow.com/questions/13764789/…
Goswin

0

ไม่ไม่มีโครงสร้างดังกล่าวใน C # แต่คอมไพเลอร์. NET JIT สามารถตัดสินใจที่จะทำการเรียกฟังก์ชั่นแบบอินไลน์ในเวลา JIT แต่จริง ๆ แล้วฉันไม่รู้ว่ามันทำการปรับให้เหมาะสมเช่นนั้นจริงหรือไม่
(ฉันคิดว่าควร :-))


0

ในกรณีที่ชุดประกอบของคุณจะเป็น ngen-ed คุณอาจต้องการดูที่ TargetedPatchingOptOut สิ่งนี้จะช่วยให้ ngen ตัดสินใจว่าจะใช้วิธีการแบบอินไลน์หรือไม่ การอ้างอิง MSDN

มันยังคงเป็นเพียงคำใบ้เพื่อเพิ่มประสิทธิภาพ แต่ไม่ใช่คำสั่งที่จำเป็น


และ JIT จะรู้ดียิ่งขึ้นไม่ว่าจะอินไลน์หรือไม่ เห็นได้ชัดว่าจะไม่ช่วยคุณถ้า JIT ไม่ปรับการโทรให้เหมาะสม แต่ทำไมฉันต้องกังวลเกี่ยวกับค่าใช้จ่ายน้อยที่สุดของฟังก์ชั่นที่เรียกว่าเพียงไม่กี่ครั้ง
Voo

-7

นิพจน์แลมบ์ดาเป็นฟังก์ชั่นอินไลน์! ฉันคิดว่า C # ไม่มีคุณสมบัติพิเศษเช่นอินไลน์หรืออะไรแบบนั้น!


9
ฉันไม่ได้ลงคะแนนคุณ แต่โปรดอ่านคำถามและให้แน่ใจว่าคุณเข้าใจพวกเขาก่อนโพสต์คำตอบแบบสุ่ม en.wikipedia.org/wiki/Inline_function
Camilo Martin

1
คำตอบนี้ไม่ดีเท่าที่จะได้รับการทำออกมาได้ - OP มีความชัดเจนเกี่ยวกับฟังก์ชั่นอินไลน์ 'VS 'ฟังก์ชั่นแลมบ์ดา' และขออภัย MSDN อ้างถึง lambdas เป็น"งบแบบอินไลน์"หรือ"รหัสแบบอินไลน์" อย่างไรก็ตามตามคำตอบของ Konrad มีแอตทริบิวต์ที่บอกใบ้ให้คอมไพเลอร์เกี่ยวกับวิธีการทำอินไลน์
StuartLC

-7

C # ไม่สนับสนุนวิธีการแบบอินไลน์ (หรือฟังก์ชั่น) ในวิธีที่ภาษาแบบไดนามิกเช่นหลามทำ อย่างไรก็ตามวิธีการที่ไม่ระบุชื่อและ lambdas สามารถใช้เพื่อวัตถุประสงค์ที่คล้ายกันรวมถึงเมื่อคุณจำเป็นต้องเข้าถึงตัวแปรในวิธีการที่มีเช่นในตัวอย่างด้านล่าง

static void Main(string[] args)
{
    int a = 1;

    Action inline = () => a++;
    inline();
    //here a = 2
}

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