ในการตั้งค่าการสร้างขั้นสูงของ Visual Studio 2019 C # 8 ดูเหมือนจะไม่พร้อมใช้งานสำหรับโครงการ. NET Framework เท่านั้น (ดังภาพด้านล่าง) สำหรับโครงการ. NET Core 3.0:
C # 8 รองรับ. NET Framework หรือไม่
ในการตั้งค่าการสร้างขั้นสูงของ Visual Studio 2019 C # 8 ดูเหมือนจะไม่พร้อมใช้งานสำหรับโครงการ. NET Framework เท่านั้น (ดังภาพด้านล่าง) สำหรับโครงการ. NET Core 3.0:
C # 8 รองรับ. NET Framework หรือไม่
คำตอบ:
ใช่ C # 8 สามารถใช้ได้กับ. NET Frameworkและเป้าหมายอื่น ๆ ที่เก่ากว่า. NET Core 3.0 / .NET Standard 2.1 ใน Visual Studio 2019 (หรือ Visual Studio รุ่นเก่ากว่าหากคุณติดตั้งแพ็คเกจ Nuget )
ต้องตั้งค่าเวอร์ชันภาษาเป็น8.0
ในไฟล์ csproj
คุณลักษณะส่วนใหญ่ - แต่ไม่ใช่ทั้งหมด - พร้อมใช้งานแล้วแต่ว่ากรอบงานใดจะถูกกำหนดเป้าหมาย
คุณสมบัติต่อไปนี้เป็นการเปลี่ยนแปลงไวยากรณ์เท่านั้น พวกเขาทำงานโดยไม่คำนึงถึงกรอบ:
สิ่งเหล่านี้ต้องการชนิดใหม่ที่ไม่อยู่ใน. NET Framework สามารถใช้ร่วมกับแพ็กเกจ Nuget หรือไฟล์โค้ด "polyfill" เท่านั้น:
สมาชิกอินเทอร์เฟซเริ่มต้นจะไม่คอมไพล์ภายใต้. NET Framework และจะไม่ทำงานเนื่องจากต้องการการเปลี่ยนแปลงรันไทม์ใน CLR ขณะนี้. NET CLR ถูกแช่แข็งเนื่องจาก. NET Core เป็นหนทางไปข้างหน้า
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่ไม่และไม่ทำงานและใน polyfills เป็นไปได้ดูบทความจวร์ตแลงก์, C # 8.0 และ .NET มาตรฐาน 2.0 - ทำสิ่งที่ไม่สนับสนุน
โครงการ C # ต่อไปนี้กำหนดเป้าหมาย. NET Framework 4.8 และการใช้ชนิดการอ้างอิงที่เป็นโมฆะ C # 8 คอมไพล์ใน Visual Studio 16.2.0 ฉันสร้างขึ้นโดยเลือกเทมเพลต. NET Standard Class Library จากนั้นแก้ไขเพื่อกำหนดเป้าหมาย. NET Framework แทน:
.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48</TargetFrameworks>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
.cs:
namespace ClassLibrary1
{
public class Class1
{
public string? NullableString { get; set; }
}
}
จากนั้นฉันลองใช้โครงการ WinForms .NET Framework 4.5.2 โดยใช้.csproj
รูปแบบเดิมและเพิ่มคุณสมบัติประเภทการอ้างอิงที่เป็นโมฆะเดียวกัน ฉันเปลี่ยนประเภทภาษาในกล่องโต้ตอบการตั้งค่าการสร้างขั้นสูงของ Visual Studio (ปิดใช้งานใน 16.3) เป็นlatest
และบันทึกโครงการ แน่นอนว่าจุดนี้มันไม่ได้สร้าง ฉันเปิดไฟล์โครงการในโปรแกรมแก้ไขข้อความและเปลี่ยนlatest
เป็นpreview
ในการกำหนดค่าการสร้างPropertyGroup
:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>preview</LangVersion>
จากนั้นผมก็เปิดใช้งานการสนับสนุนสำหรับประเภทอ้างอิง nullable โดยการเพิ่ม<Nullable>enable</Nullable>
การหลักPropertyGroup
:
<PropertyGroup>
<Nullable>enable</Nullable>
ฉันโหลดโครงการซ้ำและสร้างขึ้น
เมื่อคำตอบนี้ถูกเขียนครั้งแรก C # 8 อยู่ในการแสดงตัวอย่างและมีงานนักสืบจำนวนมากที่เกี่ยวข้อง ฉันทิ้งข้อมูลไว้ที่นี่เพื่อลูกหลาน อย่าลังเลที่จะข้ามไปหากคุณไม่จำเป็นต้องรู้รายละเอียดเกี่ยวกับเลือดทั้งหมด
ภาษา C # ในอดีตส่วนใหญ่เป็นเฟรมเวิร์กที่เป็นกลางนั่นคือสามารถรวบรวม Framework เวอร์ชันเก่าได้แม้ว่าคุณลักษณะบางอย่างจะต้องใช้ประเภทใหม่หรือการสนับสนุน CLR ก็ตาม
ผู้ที่ชื่นชอบ C # ส่วนใหญ่จะอ่านรายการบล็อกอาคาร C # 8.0โดย Mads Torgersen ซึ่งอธิบายว่าคุณลักษณะบางอย่างของ C # 8 มีการพึ่งพาแพลตฟอร์ม:
สตรีมตัวสร้างดัชนีและช่วงของ Async ล้วนขึ้นอยู่กับประเภทเฟรมเวิร์กใหม่ที่จะเป็นส่วนหนึ่งของ. NET Standard 2.1 ... .NET Core 3.0 เช่นเดียวกับ Xamarin, Unity และ Mono ทั้งหมดจะใช้. NET Standard 2.1 แต่. NET Framework 4.8 จะ ไม่. ซึ่งหมายความว่าประเภทที่จำเป็นในการใช้คุณสมบัติเหล่านี้จะไม่พร้อมใช้งานบน. NET Framework 4.8
สิ่งนี้ดูเหมือนValue Tuplesซึ่งถูกนำมาใช้ใน C # 7 คุณลักษณะนั้นต้องการประเภทใหม่ - ValueTuple
โครงสร้างซึ่งไม่มีใน NET Framework เวอร์ชันที่ต่ำกว่า 4.7 หรือ. NET Standard ที่เก่ากว่า 2.0 อย่างไรก็ตาม , C # 7 ยังสามารถนำมาใช้ในรุ่นเก่าของ .NET อย่างใดอย่างหนึ่งโดยไม่ต้อง tuples ค่าหรือกับพวกเขาโดยการติดตั้งแพคเกจ System.ValueTuple Nuget Visual Studio เข้าใจสิ่งนี้และทุกอย่างก็ดีกับโลก
อย่างไรก็ตาม Mads ยังเขียนว่า:
ด้วยเหตุนี้การใช้ C # 8.0 จึงได้รับการสนับสนุนบนแพลตฟอร์มที่ใช้. NET Standard 2.1 เท่านั้น
... ซึ่งถ้าเป็นจริงจะตัดออกโดยใช้ C # 8 กับ. NET Framework เวอร์ชันใดก็ได้และแม้แต่ในไลบรารี. NET Standard 2.0 ซึ่งเมื่อไม่นานมานี้เราได้รับการสนับสนุนให้ใช้เป็นเป้าหมายพื้นฐานสำหรับรหัสไลบรารี คุณจะไม่สามารถใช้กับ. NET Core เวอร์ชันเก่ากว่า 3.0 ได้เนื่องจากสนับสนุนเฉพาะ. NET Standard 2.0
การสอบสวนดำเนินไปแล้ว! -
Jon Skeet มี Noda-Time เวอร์ชันอัลฟ่าที่ใช้ C # 8 พร้อมที่จะไปซึ่งกำหนดเป้าหมาย. NET Standard 2.0 เท่านั้น เขาคาดหวังอย่างชัดเจนว่า C # 8 / .NET Standard 2.0 จะรองรับเฟรมเวิร์กทั้งหมดในตระกูล. NET (ดูบล็อกโพสต์ของ Jon "ขั้นตอนแรกที่มีประเภทการอ้างอิงที่เป็นโมฆะ" )
พนักงานของ Microsoft ได้พูดคุยเกี่ยวกับ Visual Studio UI สำหรับประเภทการอ้างอิงที่เป็นโมฆะC # 8 บน GitHubและมีการระบุว่าพวกเขาตั้งใจที่จะสนับสนุนระบบเดิมcsproj
(รูปแบบ pre -.NET Core SDK csproj
) นี่เป็นข้อบ่งชี้ที่ชัดเจนมากว่า C # 8 จะสามารถใช้งานได้กับ. NET Framework [ฉันสงสัยว่าพวกเขาจะย้อนกลับไปในตอนนี้เนื่องจากมีการปิดใช้งานดรอปดาวน์เวอร์ชันภาษา Visual Studio 2019 และ. NET เชื่อมโยงกับ C # 7.3]
ไม่นานหลังจากโพสต์บล็อกที่มีชื่อเสียงเธรด GitHub ได้กล่าวถึงการสนับสนุนข้ามแพลตฟอร์ม จุดสำคัญที่เกิดขึ้นคือ. NET Standard 2.1 จะมีเครื่องหมายที่แสดงว่ารองรับการใช้งานอินเทอร์เฟซเริ่มต้น - คุณลักษณะนี้ต้องการการเปลี่ยนแปลง CLR ที่จะไม่สามารถใช้ได้กับ. NET Framework นี่คือบิตที่สำคัญจาก Immo Landwerth ผู้จัดการโปรแกรมในทีม. NET ที่ Microsoft:
คอมไพเลอร์ (เช่น C #) คาดว่าจะใช้การมีอยู่ของฟิลด์นี้เพื่อตัดสินใจว่าจะอนุญาตให้ใช้อินเทอร์เฟซเริ่มต้นหรือไม่ หากมีฟิลด์อยู่รันไทม์คาดว่าจะสามารถโหลดและรันโค้ดผลลัพธ์ได้
ทั้งหมดนี้ชี้ไปที่ "C # 8.0 ได้รับการสนับสนุนเฉพาะบนแพลตฟอร์มที่ใช้. NET Standard 2.1" ซึ่งเป็นการทำให้เข้าใจง่ายเกินไปและ C # 8 จะรองรับ. NET Framework แต่เนื่องจากมีความไม่แน่นอนมากฉันจึงถาม GitHubและ HaloFour ตอบว่า:
IIRC คุณลักษณะเดียวที่จะไม่ปรากฏบน. NET Framework อย่างแน่นอนคือ DIM (วิธีการเชื่อมต่อเริ่มต้น) เนื่องจากต้องมีการเปลี่ยนแปลงรันไทม์ คุณสมบัติอื่น ๆ ถูกขับเคลื่อนโดยรูปร่างของคลาสที่อาจไม่ถูกเพิ่มลงใน. NET Framework แต่สามารถเติมแบบ polyfilled ผ่านโค้ดของคุณเองหรือ NuGet (ช่วงดัชนีตัววนซ้ำ async การกำจัดแบบ async)
Victor Derks ให้ความเห็นว่า " แอตทริบิวต์ nullable ใหม่ที่จำเป็นในการออกแบบกรณีการใช้งาน nullable ที่ซับซ้อนมากขึ้นมีเฉพาะใน System.Runtime.dll ที่มาพร้อมกับ. NET Core 3.0 และ. NET Standard 2.1 ... [และ] เข้ากันไม่ได้กับ. NET Framework 4.8"
อย่างไรก็ตาม Immo Landwerth ให้ความเห็นว่า "API ส่วนใหญ่ของเราไม่จำเป็นต้องมีแอตทริบิวต์ที่กำหนดเองใด ๆ เนื่องจากประเภทเป็นแบบทั่วไปหรือไม่เป็นค่าว่าง" ในบทความลองใช้ประเภทการอ้างอิงที่เป็นโมฆะ
Ben Hallยกปัญหาความพร้อมใช้งานของแอตทริบิวต์ที่เป็นโมฆะนอก Core 3.0บน GitHub โดยมีความเห็นต่อไปนี้จากพนักงานของ Microsoft หมายเหตุ:
C # 8 จะรองรับอย่างสมบูรณ์บน. net core 3.0 และ. net มาตรฐาน 2.1 เท่านั้น หากคุณแก้ไขไฟล์โปรเจ็กต์ด้วยตนเองเพื่อใช้ C # 8 กับ. net core 2.1 แสดงว่าคุณอยู่ในพื้นที่ที่ไม่รองรับ คุณสมบัติ C # 8 บางอย่างจะทำงานได้ดีคุณสมบัติ C # 8 บางอย่างจะทำงานได้ไม่ดีนัก (เช่นประสิทธิภาพต่ำ) คุณสมบัติ C # 8 บางอย่างจะทำงานร่วมกับแฮ็กพิเศษและคุณสมบัติ C # 8 บางอย่างจะไม่ทำงานเลย ซับซ้อนมากที่จะอธิบาย เราไม่ได้ปิดกั้นมันเพื่อให้ผู้ใช้ผู้เชี่ยวชาญที่สามารถนำทางผ่านไปได้ ฉันไม่แนะนำให้ใช้มิกซ์แอนด์แมตช์ที่ไม่รองรับนี้ให้ใช้ในวงกว้าง
(มนโคทัส)
คนอย่างคุณที่เต็มใจเข้าใจ - และหลีกเลี่ยงพวกเขา - มีอิสระที่จะใช้ C # 8 ประเด็นก็คือคุณสมบัติภาษาบางอย่างจะไม่สามารถใช้ได้กับเป้าหมายระดับล่าง
(อิมโมแลนด์เวิร์ ธ )
มีการเปลี่ยนแปลงที่สำคัญในเวอร์ชัน RTM ของ Visual Studio 2019 เวอร์ชัน 16.3 - เวอร์ชันเปิดตัวสำหรับ C # 8.0: ดรอปดาวน์การเลือกภาษาถูกปิดใช้งาน:
เหตุผลของ Microsoft สำหรับสิ่งนี้คือ:
ก้าวต่อไป ... แต่ละเวอร์ชันของแต่ละเฟรมเวิร์กจะมีเวอร์ชันที่รองรับและเวอร์ชันเริ่มต้นเพียงเวอร์ชันเดียวและเราจะไม่รองรับเวอร์ชันที่กำหนดเอง เพื่อแสดงถึงการเปลี่ยนแปลงในการสนับสนุนนี้การกระทำนี้จะปิดใช้งานกล่องคำสั่งผสมเวอร์ชันภาษาอย่างถาวรและเพิ่มลิงก์ไปยังเอกสารที่อธิบายการเปลี่ยนแปลง
เอกสารซึ่งเปิดเป็นเวอร์ชันภาษา C # รายการนี้แสดง C # 8.0 เป็นภาษาเริ่มต้นสำหรับ. NET Core 3.x เท่านั้น นอกจากนี้ยังยืนยันว่าแต่ละเวอร์ชันของแต่ละเฟรมเวิร์กจะมีเวอร์ชันที่รองรับและเวอร์ชันเริ่มต้นเพียงเวอร์ชันเดียวและไม่สามารถพึ่งพาเฟรมเวิร์กไม่เชื่อเรื่องพระเจ้าของภาษาได้อีกต่อไป
เวอร์ชันภาษายังคงสามารถบังคับเป็น 8 สำหรับโครงการ. NET Framework ได้โดยแก้ไขไฟล์. csproj
ชุดค่าผสม C # 8 / .NET Framework ไม่ได้รับการสนับสนุนอย่างเป็นทางการจาก Microsoft พวกเขากล่าวว่าสำหรับผู้เชี่ยวชาญเท่านั้น
<Nullable>enable</Nullable>
ในไฟล์csproj
. ดูเหมือนว่าจะได้ผลเมื่อใช้#nullable enable
คำสั่ง ดูเพิ่มเติมที่: github.com/dotnet/project-system/issues/5551
ตามรายการบล็อกนี้ภาษานั้นเชื่อมโยงกับกรอบ:
ซึ่งหมายความว่าประเภทที่จำเป็นในการใช้คุณสมบัติเหล่านี้จะไม่พร้อมใช้งานบน. NET Framework 4.8 ในทำนองเดียวกันการใช้งานสมาชิกอินเทอร์เฟซเริ่มต้นจะอาศัยการปรับปรุงรันไทม์ใหม่และเราจะไม่สร้างสิ่งเหล่านี้ใน. NET Runtime 4.8 เช่นกัน
ด้วยเหตุนี้การใช้ C # 8.0 จึงได้รับการสนับสนุนบนแพลตฟอร์มที่ใช้. NET Standard 2.1 เท่านั้น ความจำเป็นในการทำให้รันไทม์มีเสถียรภาพทำให้เราไม่สามารถใช้งานคุณสมบัติภาษาใหม่ ๆ ได้มานานกว่าทศวรรษ ด้วยลักษณะแบบเคียงข้างกันและลักษณะโอเพ่นซอร์สของช่วงเวลาที่ทันสมัยเรารู้สึกว่าเราสามารถพัฒนามันอีกครั้งอย่างมีความรับผิดชอบและออกแบบภาษาโดยคำนึงถึงสิ่งนั้น สก็อตอธิบายในการอัปเดตบน. NET Core 3.0 และ. NET Framework 4.8 ว่า. NET Framework จะเห็นนวัตกรรมน้อยลงในอนาคตแทนที่จะเน้นที่ความเสถียรและความน่าเชื่อถือ ด้วยเหตุนี้เราจึงคิดว่ามันเป็นการดีกว่าที่จะพลาดคุณสมบัติทางภาษาบางอย่างมากกว่าที่จะไม่มีใครได้รับ
C # 8.0 (และสูงกว่า) รองรับเฉพาะบน. NET Core 3.x และเวอร์ชันที่ใหม่กว่า คุณลักษณะใหม่ล่าสุดจำนวนมากต้องการคุณสมบัติไลบรารีและรันไทม์ที่นำมาใช้ในการกำหนดเวอร์ชันภาษา . NET Core 3.x: C #