Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu öğreticide .NET'te sürüm oluşturmanın ne anlama geldiğini öğreneceksiniz. Ayrıca, kitaplığınızın sürümünü oluştururken ve kitaplığın yeni bir sürümüne yükseltirken göz önünde bulundurmanız gereken faktörleri de öğreneceksiniz.
Dil sürümü
C# derleyicisi .NET SDK'sının bir parçasıdır. Varsayılan olarak, derleyici projeniz için seçilen TFM ile eşleşen C# dil sürümünü seçer. SDK sürümü seçtiğiniz çerçeveden daha büyükse, derleyici daha büyük bir dil sürümü kullanabilir. Projenizde LangVersion öğesini ayarlayarak varsayılanı değiştirebilirsiniz. Nasıl yapılacağını derleyici seçenekleriyle ilgili makalemizde öğrenebilirsiniz.
Uyarı
öğesinin LangVersion olarak latest ayarlanması önerilmez. ayarı, latest yüklenen derleyicinin en son sürümünü kullandığı anlamına gelir. Bu, makineden makineye değişerek derlemeleri güvenilmez hale getirebilir. Buna ek olarak, geçerli SDK'da yer almamış çalışma zamanı veya kitaplık özellikleri gerektirebilecek dil özelliklerini etkinleştirir.
Kütüphane Oluşturma Araçları
Genel kullanım için .NET kitaplıkları oluşturan bir geliştirici olarak, büyük olasılıkla yeni güncelleştirmeleri kullanıma sunmanız gereken durumlarda bulundunuz. Mevcut kodun kitaplığınızın yeni sürümüne sorunsuz bir şekilde geçirilmesini sağlamak için bu işleme nasıl gittiğiniz çok önemlidir. Yeni bir sürüm oluştururken göz önünde bulundurmanız gereken birkaç şey şunlardır:
Anlamsal Sürüm Oluşturma
Anlamsal sürüm oluşturma (kısaca SemVer), belirli kilometre taşı olaylarını göstermek için kitaplığınızın sürümlerine uygulanan bir adlandırma kuralıdır. İdeal olarak, kitaplığınıza verdiğiniz sürüm bilgileri geliştiricilerin aynı kitaplığın eski sürümlerini kullanan projeleriyle uyumluluğu belirlemesine yardımcı olmalıdır.
SemVer'e en temel yaklaşım, 3 bileşen biçimidir MAJOR.MINOR.PATCHve burada:
-
MAJORuyumsuz API değişiklikleri yaptığınızda artırılır -
MINORgeriye dönük uyumlu bir şekilde işlev eklediğinizde artırılır -
PATCHgeriye dönük uyumlu hata düzeltmeleri yaptığınızda artırılır
Örneklerle sürüm artışlarını anlama
Her sürüm numarasının ne zaman artırıldığında netleştirilmesine yardımcı olmak için somut örnekler aşağıda verilmiştir:
MAJOR sürüm artışları (uyumsuz API değişiklikleri)
Bu değişiklikler, kullanıcıların kodlarını yeni sürümle çalışacak şekilde değiştirmelerini gerektirir:
Genel erişilebilir yöntem veya özelliği kaldırma:
// Version 1.0.0 public class Calculator { public int Add(int a, int b) => a + b; public int Subtract(int a, int b) => a - b; // This method exists } // Version 2.0.0 - MAJOR increment required public class Calculator { public int Add(int a, int b) => a + b; // Subtract method removed - breaking change! }Yöntem imzalarını değiştirme:
// Version 1.0.0 public void SaveFile(string filename) { } // Version 2.0.0 - MAJOR increment required public void SaveFile(string filename, bool overwrite) { } // Added required parameterMevcut yöntemlerin davranışını beklentileri bozacak şekilde değiştirme:
// Version 1.0.0 - returns null when file not found public string ReadFile(string path) => File.Exists(path) ? File.ReadAllText(path) : null; // Version 2.0.0 - MAJOR increment required public string ReadFile(string path) => File.ReadAllText(path); // Now throws exception when file not found
MINOR sürüm artışları (geriye dönük uyumlu işlevsellik)
Bu değişiklikler mevcut kodu bozmadan yeni özellikler ekler:
Yeni genel yöntemler veya özellikler ekleme:
// Version 1.0.0 public class Calculator { public int Add(int a, int b) => a + b; } // Version 1.1.0 - MINOR increment public class Calculator { public int Add(int a, int b) => a + b; public int Multiply(int a, int b) => a * b; // New method added }Yeni aşırı yüklemeler ekleme:
// Version 1.0.0 public void Log(string message) { } // Version 1.1.0 - MINOR increment public void Log(string message) { } // Original method unchanged public void Log(string message, LogLevel level) { } // New overload addedMevcut yöntemlere isteğe bağlı parametreler ekleme:
// Version 1.0.0 public void SaveFile(string filename) { } // Version 1.1.0 - MINOR increment public void SaveFile(string filename, bool overwrite = false) { } // Optional parameterNot
Bu kaynak uyumlu bir değişikliktir, ancak ikili uyumluluğu bozan bir değişikliktir. Bu kitaplığı kullananların, kitaplığın düzgün çalışması için yeniden derleme yapması gerekiyor. Birçok kitaplık bunu ikincil sürüm değişikliklerinde değil yalnızca ana sürüm değişikliklerinde dikkate alır.
PATCH sürüm artışları (geriye dönük uyumlu hata düzeltmeleri)
Bu değişiklikler yeni özellikler eklemeden veya mevcut işlevleri bozmadan sorunları düzeltir:
Mevcut bir yöntemin uygulamasındaki bir hatayı düzeltme:
// Version 1.0.0 - has a bug public int Divide(int a, int b) { return a / b; // Bug: doesn't handle division by zero } // Version 1.0.1 - PATCH increment public int Divide(int a, int b) { if (b == 0) throw new ArgumentException("Cannot divide by zero"); return a / b; // Bug fixed, behavior improved but API unchanged }API'yi değiştirmeyen performans geliştirmeleri:
// Version 1.0.0 public List<int> SortNumbers(List<int> numbers) { return numbers.OrderBy(x => x).ToList(); // Slower implementation } // Version 1.0.1 - PATCH increment public List<int> SortNumbers(List<int> numbers) { var result = new List<int>(numbers); result.Sort(); // Faster implementation, same API return result; }
Temel ilke şudur: Mevcut kod herhangi bir değişiklik yapmadan yeni sürümünüzü kullanabiliyorsa, bu bir MINOR veya PATCH güncelleştirmesidir. Mevcut kodun yeni sürümünüzle çalışması için değiştirilmesi gerekiyorsa, bu bir MAJOR güncelleştirmesidir.
Sürüm bilgilerini .NET kitaplığınıza uygularken sürüm öncesi sürümler gibi diğer senaryoları belirtmenin yolları da vardır.
Geriye Dönük Uyumluluk
Kitaplığınızın yeni sürümlerini yayımladığınızda, büyük olasılıkla önceki sürümlerle geriye dönük uyumluluk önemli sorunlarınızdan biri olacaktır. Kitaplığınızın yeni bir sürümü, önceki sürüme bağlı kod yeniden derlendiğinde yeni sürümle çalışabiliyorsa, önceki sürümle uyumlu kaynaktır. Kitaplığınızın yeni sürümü, eski sürüme bağımlı olan bir uygulama yeniden derleme olmadan yeni sürümle çalışabilirse ikili uyumludur.
Kitaplığınızın eski sürümleriyle geriye dönük uyumluluğu korumaya çalışırken göz önünde bulundurmanız gereken bazı şeyler şunlardır:
- Sanal yöntemler: Yeni sürümünüzde sanal olmayan bir yöntem yaptığınızda, bu yöntemi geçersiz kılan projelerin güncelleştirilmiş olması gerekir. Bu, büyük bir kırılma değişikliğidir ve kesinlikle yapılması önerilmez.
- Yöntem imzaları: Yöntem davranışını güncelleştirmenin imzasını da değiştirmenizi gerektirdiği durumlarda, bunun yerine bir aşırı yükleme oluşturun, böylece bu yönteme yapılan kod çağrısı çalışmaya devam edebilir. Uygulamanın tutarlı kalması için eski yöntem imzasını her zaman yeni yöntem imzasına çağırmak üzere değiştirebilirsiniz.
- Eski öznitelik: Kodunuzda bu özniteliği kullanarak kullanım dışı bırakılan ve gelecekteki sürümlerde kaldırılma olasılığı olan sınıfları veya sınıf üyelerini belirtebilirsiniz. Bu, kitaplığınızı kullanan geliştiricilerin köklü değişikliklere karşı daha iyi hazırlıklı olmasını sağlar.
- İsteğe Bağlı Yöntem Bağımsız Değişkenleri: Daha önce isteğe bağlı yöntem bağımsız değişkenlerini zorunlu hale getirdiğinizde veya varsayılan değerlerini değiştirdiğinizde, bu bağımsız değişkenleri sağlamayan tüm kodların güncelleştirilmesi gerekir.
Not
Bağımsız değişkenleri zorunludan isteğe bağlıya çevirmek, eğer yöntemin davranışını değiştirmezse, özellikle çok az etki yaratmalıdır.
Kullanıcılarınızın kitaplığınızın yeni sürümüne yükseltmesini ne kadar kolay hale getirirseniz, yükseltme olasılığı o kadar artar.
Uygulama Yapılandırma Dosyası
.NET geliştiricisi olarak, çoğu proje türünde mevcut olan dosyayla app.config karşılaşma olasılığınız çok yüksektir.
Bu basit yapılandırma dosyası, yeni güncelleştirmelerin dağıtımını geliştirmek için uzun bir yol kat edebilir. Kitaplıklarınızı genellikle düzenli olarak değişme olasılığı olan bilgilerin dosyada app.config depolandığı şekilde tasarlamanız gerekir. Bu şekilde, bu bilgiler güncelleştirildiğinde, kitaplığın yeniden derlenmesine gerek kalmadan eski sürümlerin yapılandırma dosyasının yenisiyle değiştirilmesi gerekir.
Kitaplıkları Kullanma
Diğer geliştiriciler tarafından oluşturulan .NET kitaplıklarını kullanan bir geliştirici olarak, büyük olasılıkla kitaplığın yeni sürümünün projenizle tam olarak uyumlu olmayabileceğini ve bu değişikliklerle çalışmak için kodunuzu güncelleştirmeniz gerektiğini fark edebilirsiniz.
Şanslısınız ki C# ve .NET ekosistemi, uygulamamızı hataya neden olabilecek yeni kitaplık sürümleriyle çalışacak şekilde kolayca güncelleştirmemize olanak sağlayan özellikler ve tekniklerle birlikte gelir.
Derleme Bağlama Yeniden Yönlendirme
Uygulamanızın kullandığı kitaplığın sürümünü güncelleştirmek için app.config dosyasını kullanabilirsiniz. Bağlama yeniden yönlendirmesi olarak adlandırılan özelliği ekleyerek uygulamanızı yeniden derlemek zorunda kalmadan yeni kitaplık sürümünü kullanabilirsiniz. Aşağıdaki örnekte, uygulamanızın app.config dosyasını ilk derlendiği sürüm yerine 1.0.1 düzeltme eki sürümünü ReferencedLibrary kullanacak 1.0.0 şekilde nasıl güncelleştirdiğiniz gösterilmektedir.
<dependentAssembly>
<assemblyIdentity name="ReferencedLibrary" publicKeyToken="32ab4ba45e0a69a1" culture="en-us" />
<bindingRedirect oldVersion="1.0.0" newVersion="1.0.1" />
</dependentAssembly>
Not
Bu yaklaşım, ReferencedLibrary'nin yeni sürümü uygulamanızla ikili olarak uyumluysa çalışır.
Uyumluluğu belirlerken dikkat edilmesi gereken değişiklikler için yukarıdaki Geriye Dönük Uyumluluk bölümüne bakın.
Yeni
Bir temel sınıfın devralınan new üyelerini gizlemek için değiştiriciyi kullanırsınız. Bu, türetilmiş sınıfların temel sınıflardaki güncelleştirmelere yanıt vermesinin bir yoludur.
Aşağıdaki örneğe göz atın:
public class BaseClass
{
public void MyMethod()
{
Console.WriteLine("A base method");
}
}
public class DerivedClass : BaseClass
{
public new void MyMethod()
{
Console.WriteLine("A derived method");
}
}
public static void Main()
{
BaseClass b = new BaseClass();
DerivedClass d = new DerivedClass();
b.MyMethod();
d.MyMethod();
}
Çıktı
A base method
A derived method
Yukarıdaki örnekten, DerivedClass ile MyMethod içinde mevcut olan BaseClass yönteminin nasıl gizlendiğini görebilirsiniz.
Başka bir deyişle, kitaplığın yeni sürümündeki bir temel sınıf türetilmiş sınıfınızda zaten var olan bir üye eklediğinde, temel sınıf üyesini new gizlemek için türetilmiş sınıf üyenizdeki değiştiriciyi kullanmanız yeterlidir.
new Değiştirici belirtilmediğinde, türetilmiş bir sınıf varsayılan olarak bir temel sınıfta çakışan üyeleri gizler, ancak derleyici uyarısı oluşturulsa da kod yine de derlenir. Başka bir deyişle, mevcut bir sınıfa yeni üyeler eklemek, kitaplığınızın bu yeni sürümünün hem kaynak hem de ikili sürümüne bağımlı olan kodla uyumlu olmasını sağlar.
geçersiz kılma
override değiştiricisi, türetilmiş bir uygulamanın bir temel sınıf üyesinin uygulamasını gizlemek yerine genişlettiğini belirtir. Temel sınıf üyesine değiştiricinin virtual uygulanmış olması gerekir.
public class MyBaseClass
{
public virtual string MethodOne()
{
return "Method One";
}
}
public class MyDerivedClass : MyBaseClass
{
public override string MethodOne()
{
return "Derived Method One";
}
}
public static void Main()
{
MyBaseClass b = new MyBaseClass();
MyDerivedClass d = new MyDerivedClass();
Console.WriteLine($"Base Method One: {b.MethodOne()}");
Console.WriteLine($"Derived Method One: {d.MethodOne()}");
}
Çıktı
Base Method One: Method One
Derived Method One: Derived Method One
Modifikatör override derleme zamanında değerlendirilir ve geçersiz kılınacak bir sanal üye bulamazsa derleyici bir hata verir.
Tartışılan teknikler hakkında bilginiz ve bunların hangi durumlarda kullanılacağına ilişkin anlayışınız, kitaplığın sürümleri arasındaki geçişi kolaylaştırmaya yönelik uzun bir yol kat edecektir.