Şu an için hala Roslyn derleyicisi tarafından kutudan çıkarılmıyor ...
Şimdiye kadar, uzantı özellikleri C # standardının önceki sürümlerine dahil edilecek kadar değerli görülmüyordu. C # 7 ve C # 8.0 bunu teklif şampiyonu olarak gördüler, ancak henüz yayınlanmadı, çünkü zaten bir uygulama olsa bile, en baştan doğru yapmak istiyorlar.
Fakat olacak ...
C # 7 çalışma listesinde bir uzantı üyeleri öğesi vardır, bu nedenle yakın gelecekte desteklenebilir. Extension özelliğinin geçerli durumu Github'da ilgili öğenin altında bulunabilir .
Bununla birlikte, özellikle özelliklere ve statik sınıflara ve hatta alanlara odaklanarak "her şeyi genişlet" olan daha da umut verici bir konu var .
Ayrıca bir geçici çözüm kullanabilirsiniz
Bu belirtildiği gibi makalesinde , kullanabileceğiniz TypeDescriptor
çalışma zamanında bir nesne örneğine bir öznitelik eklemek için yeteneği. Ancak, standart özelliklerin sözdizimini kullanmaz.
Sadece sözdizimsel şekerden biraz farklıdır, verileri sınıfa depolarken
string Data(this MyClass instance)
uzatma yöntemi için bir takma ad gibi genişletilmiş bir özellik tanımlama olanağı ekler
string GetData(this MyClass instance)
.
Umarım C # 7 tam özellikli bir uzantı sağlar her şey (özellikler ve alanlar), ancak bu noktada, sadece zaman söyleyecektir.
Ve yarının yazılımı topluluktan geleceği için katkıda bulunmaktan çekinmeyin.
Güncelleme: Ağustos 2016
Dotnet ekibi C # 7.0'daki yenilikleri ve Mads Torgensen'in bir yorumundan yayınladı :
Uzatma özellikleri: yaz boyunca onları bir deney olarak uygulayan (parlak!) Bir stajyerimiz vardı. Bununla ilgilenmeye devam ediyoruz, ancak bu büyük bir değişiklik ve buna değdiğinden emin olmamız gerekiyor.
Uzatma mülkleri ve diğer üyeler, Roslyn'in gelecekteki bir sürümüne dahil edilmesi için hala iyi adaylar gibi görünüyor, ancak belki de 7.0 değil.
Güncelleme: Mayıs 2017
Uzatma üyeleri arasında kopyası olarak kapatıldı uzatma herşey konuyla çok kapalıdır. Ana tartışma aslında geniş anlamda Tip genişletilebilirliği hakkındaydı. Özellik şimdi bir teklif olarak izleniyorve 7,0 kilometre taşından kaldırıldı.
Güncelleme: Ağustos, 2017 - C # 8.0 önerilen özellik
Hala önerilen bir özellik olarak kalmasına rağmen , şimdi sözdizimi ne olacağına dair daha net bir görüşe sahibiz. Bunun, uzantı yöntemleri için de yeni sözdizimi olacağını unutmayın:
public interface IEmployee
{
public decimal Salary { get; set; }
}
public class Employee
{
public decimal Salary { get; set; }
}
public extension MyPersonExtension extends Person : IEmployee
{
private static readonly ConditionalWeakTable<Person, Employee> _employees =
new ConditionalWeakTable<Person, Employee>();
public decimal Salary
{
get
{
// `this` is the instance of Person
return _employees.GetOrCreate(this).Salary;
}
set
{
Employee employee = null;
if (!_employees.TryGetValue(this, out employee)
{
employee = _employees.GetOrCreate(this);
}
employee.Salary = value;
}
}
}
IEmployee person = new Person();
var salary = person.Salary;
Kısmi sınıflara benzer, ancak farklı bir montajda ayrı bir sınıf / tür olarak derlenir. Bu yolla statik üyeler ve işleçler de ekleyebileceğinizi unutmayın. Mads Torgensen podcast'inde de belirtildiği gibi , uzantının herhangi bir durumu olmaz (bu nedenle sınıfa özel yönetim ortamı üyeleri ekleyemez) , yani yönetim ortamına bağlı özel yönetim ortamı verileri ekleyemezsiniz . Bunun nedeni, dahili sözlükleri yönetmek anlamına gelmesi ve zor olabilmesidir (bellek yönetimi, vb ...). Bunun için, daha önce açıklanan TypeDescriptor
/ ConditionalWeakTable
tekniğini kullanmaya devam edebilirsiniz ve özellik uzantısıyla, güzel bir özellik altında gizler.
Sözdizimi hala bu sorunu ima ettiği için değişebilir . Örneğin, bazıları daha doğal ve daha az java ile ilgili hissedebilecekleri extends
ile değiştirilebilir for
.
Aralık 2018 Güncellemesi - Roller, Uzantılar ve statik arayüz üyeleri
Uzantı , GitHub biletinin sonu olarak açıklanan bazı dezavantajlar nedeniyle C # 8.0'a her şeyi yapmadı . Yani, tasarımı geliştirmek için bir keşif vardı. Burada Mads Torgensen, rollerin ve uzantıların ne olduğunu ve nasıl farklı olduklarını açıklıyor :
Roller, arabirimlerin belirli bir türdeki belirli değerlere uygulanmasına izin verir. Uzantılar, arabirimlerin belirli bir kod bölgesinde belirli bir türdeki tüm değerlere uygulanmasına izin verir.
İki kullanım durumunda önceki teklifin bir bölümünde görülebilir. Uzantı için yeni sözdizimi şöyle olacaktır:
public extension ULongEnumerable of ulong
{
public IEnumerator<byte> GetEnumerator()
{
for (int i = sizeof(ulong); i > 0; i--)
{
yield return unchecked((byte)(this >> (i-1)*8));
}
}
}
o zaman bunu yapabilirsiniz:
foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
WriteLine($"{e.Current:X}");
}
Ve statik bir arayüz için :
public interface IMonoid<T> where T : IMonoid<T>
{
static T operator +(T t1, T t2);
static T Zero { get; }
}
Üzerinde bir extension özelliği ekleyin int
ve int
as IMonoid<int>
:
public extension IntMonoid of int : IMonoid<int>
{
public static int Zero => 0;
}