C # 8 .NET Framework'ü destekliyor mu?


133

Visual Studio 2019 Advanced Build ayarlarında, C # 8 bir .NET Framework projesi için değil (aşağıdaki resimde olduğu gibi) bir .NET Core 3.0 projesi için kullanılabilir gibi görünmektedir:

görüntü açıklamasını buraya girin

C # 8 .NET Framework'ü destekliyor mu?

Yanıtlar:


241

Evet, C # 8, .NET Framework ve Visual Studio 2019'da (veya bir Nuget paketi yüklerseniz Visual Studio'nun daha eski sürümleri) .NET Core 3.0 / .NET Standard 2.1'den daha eski diğer hedeflerle kullanılabilir .

Dil sürümü 8.0csproj dosyasında ayarlanmalıdır .

Hepsi olmasa da çoğu özellik, hangi çerçeve hedeflenirse hedeflenirse kullanılabilir.


Çalışan özellikler

Aşağıdaki özellikler yalnızca sözdizimi değişiklikleridir; çerçeveden bağımsız olarak çalışırlar:

Çalışmak için yapılabilecek özellikler

Bunlar, .NET Framework'te olmayan yeni türler gerektirir. Yalnızca "polyfill" Nuget paketleri veya kod dosyalarıyla birlikte kullanılabilirler:

Varsayılan arayüz üyeleri - çalışmıyor

Varsayılan arabirim üyeleri .NET Framework altında derlenmez ve CLR'de çalışma zamanı değişiklikleri gerektirdiğinden asla çalışmaz. NET Core artık ileriye dönük olduğu için .NET CLR dondurulmuştur.

Neyin işe yarayıp neyin yaramadığı ve olası çoklu dolgular hakkında daha fazla bilgi için, Stuart Lang'in C # 8.0 ve .NET Standard 2.0 - Desteklenmeyen Şeyler Yapma makalesine bakın .


kod

Aşağıdaki C # projesi .NET Framework 4.8'i hedefleyen ve C # 8 null atanabilir başvuru türlerini kullanan Visual Studio 16.2.0'da derlenir. Bunu, .NET Standart Sınıf Kitaplığı şablonunu seçip ardından bunun yerine .NET Framework'ü hedefleyecek şekilde düzenleyerek oluşturdum:

.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; }
    }
}

Daha sonra eski bir .csprojbiçim kullanarak bir .NET Framework 4.5.2 WinForms projesini denedim ve aynı null atanabilir başvuru türü özelliğini ekledim. Visual Studio Gelişmiş Yapı ayarları iletişim kutusundaki (16.3'te devre dışı bırakıldı) dil türünü değiştirdim latestve projeyi kaydettim. Elbette bu noktada inşa etmiyor. Bir metin editörü proje dosyasını açtı ve değiştirilen latestiçin previewinşa konfigürasyonda PropertyGroup:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   <LangVersion>preview</LangVersion>

Sonra ekleyerek null başvuru türleri için destek etkin <Nullable>enable</Nullable>ana kadar PropertyGroup:

<PropertyGroup>
   <Nullable>enable</Nullable>

Projeyi yeniden yükledim ve inşa ediyor.


Kanlı detaylar

Bu cevap ilk yazıldığında, C # 8 ön izleme aşamasındaydı ve pek çok dedektiflik işi vardı. Bu bilgiyi gelecek nesillere bırakıyorum. Tüm kanlı ayrıntıları bilmeniz gerekmiyorsa, atlamaktan çekinmeyin.

C # dili tarihsel olarak çoğunlukla çerçeveden bağımsızdır - yani Çerçevenin eski sürümlerini derleyebilmiştir - ancak bazı özellikler yeni türler veya CLR desteği gerektirmiştir.

Çoğu C # meraklısı Mads Torgersen tarafından yazılan Building C # 8.0 blog girişini okumuş ve bu da C # 8'in belirli özelliklerinin platform bağımlılıkları olduğunu açıklamaktadır:

Zaman uyumsuz akışlar, dizin oluşturucular ve aralıkların tümü, .NET Standard 2.1'in bir parçası olacak yeni çerçeve türlerine dayanır ... .NET Core 3.0 ve Xamarin, Unity ve Mono, .NET Standard 2.1'i uygulayacak, ancak .NET Framework 4.8 değil. Bu, bu özellikleri kullanmak için gerekli türlerin .NET Framework 4.8'de kullanılamayacağı anlamına gelir.

Bu biraz C # 7'de tanıtılan Değer Tuple'larına benziyor . Bu özellik ValueTuple, 4.7'nin altındaki NET Framework sürümlerinde veya 2.0'dan daha eski .NET Standardında bulunmayan yeni türler ( yapılar) gerektiriyordu . Bununla birlikte , C # 7, değer kayıtları olmadan veya System.ValueTuple Nuget paketini yükleyerek .NET'in eski sürümlerinde hala kullanılabilir . Visual Studio bunu anladı ve her şey dünya için iyiydi.

Ancak Mads şunları da yazdı:

Bu nedenle, C # 8.0 kullanımı yalnızca .NET Standard 2.1 uygulayan platformlarda desteklenir.

... eğer true olsaydı, C # 8'i .NET Framework'ün herhangi bir sürümüyle ve hatta yakın zamanda kitaplık kodu için temel hedef olarak kullanmaya teşvik edilen .NET Standard 2.0 kitaplıklarında bile kullanmayabilirdik. Yalnızca .NET Standard 2.0'ı destekledikleri için 3.0'dan daha eski .NET Core sürümleriyle bile kullanamazsınız.

Soruşturma başladı! -

  • Jon Skeet, yalnızca .NET Standard 2.0'ı hedefleyen, kullanıma hazır C # 8 kullanan Noda-Time'ın alfa sürümüne sahiptir . Açıkça C # 8 / .NET Standard 2.0'ın .NET ailesindeki tüm çerçeveleri desteklemesini bekliyor. (Ayrıca Jon'un "Boş değer atanabilir başvuru türleriyle ilk adımlar" adlı blog gönderisine bakın ).

  • Microsoft çalışanları GitHub'da C # 8 null atanabilir referans türleri için Visual Studio csprojUI'yi tartışıyor ve mirası (pre-.NET Core SDK formatı csproj) desteklemeyi amaçladıkları belirtiliyor . Bu, C # 8'in .NET Framework ile kullanılabileceğinin çok güçlü bir göstergesidir. [Visual Studio 2019 dil sürümü açılır listesinin devre dışı bırakılması ve .NET'in C # 7.3'e bağlanması nedeniyle bundan sonra geri adım atacaklarından şüpheleniyorum]

  • Ünlü blog gönderisinden kısa bir süre sonra GitHub dizisi platformlar arası desteği tartıştı. Ortaya çıkan önemli bir nokta, .NET Standard 2.1'in, arabirimlerin varsayılan uygulamalarının desteklendiğini belirten bir işaretleyici içermesiydi - özellik, .NET Framework'te hiçbir zaman kullanılamayacak bir CLR değişikliği gerektiriyor. Microsoft'ta .NET ekibindeki Program Yöneticisi Immo Landwerth'ın önemli kısmı:

    Derleyicilerin (C # gibi), varsayılan arabirim uygulamalarına izin verip vermemeye karar vermek için bu alanın varlığını kullanması beklenir. Alan mevcutsa, çalışma zamanının ortaya çıkan kodu yükleyip yürütebilmesi beklenir.

  • Bunların hepsi "C # 8.0'ın yalnızca .NET Standard 2.1'i uygulayan platformlarda desteklendiğini" ve C # 8'in .NET Framework'ü destekleyeceğini gösterdi ancak çok fazla belirsizlik olduğu için GitHub'a sordum ve HaloFour şu yanıtı verdi:

    IIRC, .NET Framework üzerinde kesinlikle görünmeyen tek özellik DIM'dir (varsayılan arayüz yöntemleri) çünkü çalışma zamanı değişiklikleri gerektirir. Diğer özellikler, .NET Framework'e hiçbir zaman eklenemeyen, ancak kendi kodunuz veya NuGet (aralıklar, dizinler, zaman uyumsuz yineleyiciler, zaman uyumsuz imha) aracılığıyla çoklu doldurulabilen sınıfların şekline göre yönlendirilir.

  • Victor Derks , " Daha karmaşık null yapılabilir kullanım durumlarını tasarlamak için gereken yeni null yapılabilir öznitelikler yalnızca .NET Core 3.0 ve .NET Standard 2.1 ile birlikte gelen System.Runtime.dll'de mevcuttur ... [ve] .NET Framework ile uyumsuz 4.8"

  • Bununla birlikte, Immo Landwerth , "API'lerimizin büyük çoğunluğunun, Null Edilebilir Referans Türlerini Deneyin makalesi altında, türler tamamen genel veya boş olmadığından herhangi bir özel özniteliğe ihtiyaç duymadığı" yorumunu yaptı .

  • Ben Hall , GitHub'da Core 3.0 dışında null yapılabilir özniteliklerin kullanılabilirliği sorununu gündeme getirdi ve Microsoft çalışanlarının aşağıdaki yorumları dikkate değer oldu:

C # 8, yalnızca .net çekirdek 3.0 ve .net standardı 2.1'de tam olarak desteklenecektir. .Net core 2.1 ile C # 8 kullanmak için proje dosyasını manuel olarak düzenlerseniz, desteklenmeyen bölgedesiniz demektir. Bazı C # 8 özellikleri iyi çalışacak, bazı C # 8 özellikleri çok iyi çalışmayacaktır (örneğin, zayıf performans), bazı C # 8 özellikleri ekstra hacklerle çalışacak ve bazı C # 8 özellikleri hiç çalışmayacaktır. Açıklaması çok karmaşık. Aktif olarak engellemiyoruz, böylece içinde gezinebilen uzman kullanıcılar bunu yapabilir. Bu desteklenmeyen karma ve eşleştirmenin geniş çapta kullanılmasını önermem.

(Jan Kotas)

Sizin gibi anlamak isteyen ve onların etrafında çalışan insanlar C # 8'i kullanmakta özgürdür. Asıl nokta, tüm dil özelliklerinin alt seviye hedeflerde çalışmayacağıdır.

(Immo Landwerth)


Visual Studio 2019

Visual Studio 2019 sürüm 16.3'ün RTM sürümünde büyük bir değişiklik oldu - C # 8.0 için başlatma sürümü: dil seçimi açılır menüsü devre dışı bırakıldı:

görüntü açıklamasını buraya girin

Microsoft'un bunun için mantığı :

İleriye bakacak olursak, ... her çerçevenin her sürümünün desteklenen ve varsayılan tek bir sürümü olacak ve rastgele sürümleri desteklemeyeceğiz. Destekteki bu değişikliği yansıtmak için, bu kesinleştirme dil sürümü birleşik giriş kutusunu kalıcı olarak devre dışı bırakır ve değişikliği açıklayan bir belgeye bağlantı ekler.

Açılan belge C # dil sürümlemesidir . Bu, YALNIZCA .NET Core 3.x için varsayılan dil olarak C # 8.0'ı listeler. Ayrıca , her çerçevenin her sürümünün ileriye dönük olarak desteklenen ve varsayılan tek bir sürüme sahip olacağını ve dilin çerçeve agnostisizmine artık güvenilemeyeceğini doğrular .

.Csproj dosyası düzenlenerek, .NET Framework projeleri için dil sürümü yine de 8'e zorlanabilir.


Uyarı imparatoru

C # 8 / .NET Framework kombinasyonu, Microsoft tarafından resmi olarak desteklenmemektedir. Sadece uzmanlar için olduğunu söylüyorlar.


3
Bu, eğer denersek
Ben Hall

2
Daha karmaşık null yapılabilir kullanım durumlarını tasarlamak için gereken yeni null yapılabilir öznitelikler ( docs.microsoft.com/en-us/dotnet/csharp/nullable-attributes ) yalnızca .NET Core 3.0 ve. NET Standard 2.1. Bu, nullable \ C # 8.0'ı NET Framework 4.8 ile uyumsuz hale getiriyor
Victor Derks

3
@BenHall Sorununuzdan bazı çıkarımlar ekledim - sorunu gündeme getirdiğiniz ve burada yayınladığınız için çok teşekkür ederim. Lütfen herhangi bir şekilde yanlışsa cevabı düzenlemekten çekinmeyin.
Stephen Kennedy

3
Visual Studio 2019 IntelliSense, .NET Framework <Nullable>enable</Nullable>içinde belirtildiğinde null yapılabilir başvuru türlerini desteklemez csproj. #nullable enableDirektifleri kullanırken işe yarıyor gibi görünüyor . Ayrıca bkz .: github.com/dotnet/project-system/issues/5551
Bouke

3
@odalet C # 8'i hedefleyen ve polyfill gerektirmeyen (zaten bunu zaten yapıyor) ve muhtemelen polyfill'leri de (bunlara ihtiyaç duymayan) temel özellikleri kullanmak konusunda hiçbir endişem olmazdı. Ancak, alabileceğim en iyi tavsiye şudur: Şüpheniz varsa, bunu yapmayın, en azından işiniz buna bağlıysa.
Stephen Kennedy

34

Bu blog yazısına göre , dil gerçekten çerçeveye bağlıdır:

Bu, bu özellikleri kullanmak için gerekli türlerin .NET Framework 4.8'de kullanılamayacağı anlamına gelir. Benzer şekilde, varsayılan arabirim üyesi uygulamaları yeni çalışma zamanı geliştirmelerine dayanır ve bunları .NET Runtime 4.8'de de yapmayacağız.

Bu nedenle, C # 8.0 kullanımı yalnızca .NET Standard 2.1 uygulayan platformlarda desteklenir. Çalışma zamanını sabit tutma ihtiyacı, on yıldan fazla bir süredir yeni dil özelliklerini uygulamamıza engel oldu. Modern çalışma zamanlarının yan yana ve açık kaynaklı doğası ile, onları sorumlu bir şekilde yeniden geliştirebileceğimizi ve bunu akılda tutarak dil tasarımı yapabileceğimizi düşünüyoruz. Scott, .NET Core 3.0 ve .NET Framework 4.8 Güncellemesinde .NET Framework'ün gelecekte daha az yenilik göreceğini, bunun yerine kararlılık ve güvenilirliğe odaklanacağını açıkladı. Bunu göz önünde bulundurarak, bazı dil özelliklerini gözden kaçırmanın, kimsenin onları almamasından daha iyi olduğunu düşünüyoruz.


3
Stephen Kennedy'nin diğer yanıtında daha birçok ayrıntı var. Aslında, .NET Framework hedeflenirken önemli bir C # 8.0 alt kümesini çalıştırmak yeterince kolaydır. Ancak C # 8.0'ın bazı kısımları, çalışma zamanında Microsoft'un "eski" .NET Framework için yapmayacağı değişiklikler gerektiriyor. Ve dil sürümü ile .NET sürümünü birbirine daha yakından bağlıyor gibi görünüyorlar.
Jeppe Stig Nielsen

1

C # 8.0 (ve üstü) yalnızca .NET Core 3.x ve daha yeni sürümlerde desteklenir. En yeni özelliklerin çoğu, .NET Core 3.x: C # dili sürümlemede sunulan kitaplık ve çalışma zamanı özelliklerini gerektirir.


3
Yukarıda @stephen kennedy'den gelen doğru olarak işaretlenmiş cevabı gördünüz mü?
James Harcourt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.