ฉันจะเรียกวิธีการเริ่มต้นแทนการใช้งานที่เป็นรูปธรรมได้อย่างไร


9

ทำไมพฤติกรรมของวิธีการเชื่อมต่อเริ่มต้นเปลี่ยนไปใน C # 8 ในอดีตรหัสต่อไปนี้ (เมื่อวิธีการอินเทอร์เฟซเริ่มต้นถูกสาธิตไม่ออก):

interface IDefaultInterfaceMethod
{
    // By default, this method will be virtual, and the virtual keyword can be here used!
    virtual void DefaultMethod()
    {
        Console.WriteLine("I am a default method in the interface!");
    }

}

interface IOverrideDefaultInterfaceMethod : IDefaultInterfaceMethod
{
    void IDefaultInterfaceMethod.DefaultMethod()
    {
        Console.WriteLine("I am an overridden default method!");
    }
}

class AnyClass : IDefaultInterfaceMethod, IOverrideDefaultInterfaceMethod
{
}

class Program
{
    static void Main()
    {
        IDefaultInterfaceMethod anyClass = new AnyClass();
        anyClass.DefaultMethod();

        IOverrideDefaultInterfaceMethod anyClassOverridden = new AnyClass();
        anyClassOverridden.DefaultMethod();
    }
}

มีเอาต์พุตต่อไปนี้:

เอาต์พุตคอนโซล:

ฉันเป็นวิธีการเริ่มต้นในอินเทอร์เฟซ!
ฉันเป็นวิธีเริ่มต้นที่ถูกแทนที่!

แต่ด้วยเวอร์ชันล่าสุดของ C # 8 โค้ดด้านบนกำลังสร้างเอาต์พุตต่อไปนี้:

เอาต์พุตคอนโซล:

ฉันเป็นวิธีเริ่มต้นที่ถูกแทนที่!
ฉันเป็นวิธีเริ่มต้นที่ถูกแทนที่!

ทุกคนสามารถอธิบายให้ฉันฟังได้ว่าทำไมพฤติกรรมนี้ถึงเปลี่ยนไป

บันทึก:

IDefaultInterfaceMethod anyClass = new AnyClass(); anyClass.DefaultMethod();

((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??

2
ไม่มีวิธีการอินเทอร์เฟซเริ่มต้นก่อน C # 8 ผลลัพธ์ที่สองคือกรณีที่คาดไว้ - เมื่อคุณใช้วิธีการอินเทอร์เฟซคุณคาดว่าจะถูกเรียก คุณกำลังอ้างถึงข้อมูลจำเพาะรุ่นเก่าหรือไม่? ฉันคาดหวังว่ามันจะถูกละทิ้งเพราะมันทำลายพฤติกรรมที่คาดหวังของวิธีการอินเทอร์เฟซ
Panagiotis Kanavos

3
คำถามที่ดีกว่าคือ "ฉันจะเรียกวิธีการเริ่มต้นแทนการใช้งานอย่างเป็นรูปธรรมได้อย่างไร" ที่คำตอบคือ "คุณยังไม่ได้เพราะไวยากรณ์ base.DefaultMethod () ถูกทิ้งจาก C # 8"
Panagiotis Kanavos

4
นี่คือหน้าการประชุมการออกแบบที่โทรฐานมีการพูดคุยและลดลงสำหรับ C # Cut base() syntax for C# 8. We intend to bring this back in the next major release.8 สิ่งนี้ต้องการการสนับสนุนรันไทม์เพื่อให้ทำงานได้อย่างถูกต้อง
Panagiotis Kanavos

3
อินเทอร์เฟซเป็นอินเทอร์เฟซเสมอ เมื่อฉันใช้วิธีการอินเทอร์เฟซฉันคาดว่าลูกค้าทั้งหมดจะเรียกวิธีการใช้งาน ลูกค้าไม่ควรสนใจว่าคลาสใดจะใช้วิธีการอย่างใดอย่างหนึ่ง - พวกเขามีอินเทอร์เฟซและพวกเขาเรียกมันว่า
Panagiotis Kanavos

2
สำหรับไวยากรณ์ที่คุณโพสต์นั้นจะต้องมาจากข้อเสนอแบบเก่าจริงๆ - DIM สามารถเรียกได้อย่างชัดเจนเช่นอินเทอร์เฟซที่ใช้งานอย่างชัดเจน ข้อเสนอที่ว่าใช้ไวยากรณ์อินเตอร์เฟซที่ชัดเจน ... ทำตรงข้ามของvirtualผมคิดว่า? และอาจแนะนำเพชรมรดก
Panagiotis Kanavos

คำตอบ:


6

ฉันสงสัยว่าจะมีคำถามที่ดีกว่านี้:

ฉันจะเรียกวิธีการเริ่มต้นแทนการใช้งานอย่างเป็นรูปธรรมได้อย่างไร

คุณลักษณะถูกวางแผน แต่ถูกตัดออกจาก C # 8 ในเดือนเมษายน 2019เนื่องจากการใช้งานที่มีประสิทธิภาพจะต้องได้รับการสนับสนุนจากรันไทม์ ไม่สามารถเพิ่มได้ในเวลาก่อนที่จะเผยแพร่ คุณลักษณะนี้จะต้องทำงานได้ดีทั้งสำหรับ C # และ VB.NET - F # ไม่ชอบอินเทอร์เฟซอยู่ดี

ถ้า BM ไม่ปรากฎ ณ รันไทม์จะมีการเรียก AM () สำหรับ base () และส่วนต่อประสานสิ่งนี้ไม่ได้รับการสนับสนุนจากรันไทม์ดังนั้นการโทรจะส่งข้อยกเว้นแทน เราต้องการเพิ่มการสนับสนุนสำหรับสิ่งนี้ในรันไทม์ แต่มันแพงเกินไปที่จะปล่อยรุ่นนี้

เรามีวิธีแก้ไขปัญหาบางอย่าง แต่พวกเขาไม่มีพฤติกรรมที่เราต้องการและไม่ใช่ codegen ที่ต้องการ

การใช้งาน C # ของเรานั้นสามารถใช้งานได้แม้ว่าจะไม่ใช่สิ่งที่เราต้องการ แต่การใช้ VB นั้นยากกว่ามาก นอกจากนี้การใช้งานสำหรับ VB จะต้องใช้วิธีการใช้งานอินเตอร์เฟซที่จะเป็นพื้นผิวสาธารณะ API

มันจะทำงานผ่านการbase()โทรคล้ายกับวิธีการเรียน การทำสำเนาตัวอย่างข้อเสนอ:

interface I1
{ 
    void M(int) { }
}

interface I2
{
    void M(short) { }
}

interface I3
{
    override void I1.M(int) { }
}

interface I4 : I3
{
    void M2()
    {
        base(I3).M(0) // What does this do?
    }
}

ฉันจะทิ้งไว้ซักพักหนึ่งก่อนทำเครื่องหมายคำตอบ บางทีคุณอาจได้รับคะแนนโหวตเพิ่มขึ้นสำหรับการทำงานที่ดีของคุณ :-) ขอบคุณ!
Bassam Alugili

1
@BassamAlugili เพียงเพราะมีคนถามสิ่งที่คล้ายกันเมื่อเดือนที่แล้ว Why would you do that?กลับมาแล้วผมว่า จากนั้นฉันก็พบรายงานการประชุม
Panagiotis Kanavos
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.