Per il momento non è ancora supportato dal compilatore Roslyn out of the box ...
Fino ad ora, le proprietà dell'estensione non erano considerate sufficientemente valide per essere incluse nelle versioni precedenti dello standard C #. C # 7 e C # 8.0 lo hanno visto come campione della proposta ma non è stato ancora rilasciato, soprattutto perché anche se c'è già un'implementazione, vogliono farlo fin dall'inizio.
Ma sarà ...
C'è un elemento dei membri di estensione nell'elenco di lavoro di C # 7, quindi potrebbe essere supportato nel prossimo futuro. Lo stato corrente della proprietà dell'estensione può essere trovato su Github nella voce relativa .
Tuttavia, esiste un argomento ancora più promettente che è "estendere tutto" con particolare attenzione alle proprietà e alle classi statiche o persino ai campi.
Inoltre puoi usare una soluzione alternativa
Come specificato in questo articolo , è possibile utilizzare la TypeDescriptor
funzionalità per collegare un attributo a un'istanza di oggetto in fase di esecuzione. Tuttavia, non utilizza la sintassi delle proprietà standard.
È un po 'diverso dal semplice zucchero sintattico che aggiunge la possibilità di definire una proprietà estesa
string Data(this MyClass instance)
come un alias per il metodo di estensione
string GetData(this MyClass instance)
mentre memorizza i dati nella classe.
Spero che C # 7 fornirà un'estensione completa di tutto (proprietà e campi), tuttavia su quel punto, solo il tempo potrà dirlo.
E sentiti libero di contribuire dato che il software di domani verrà dalla community.
Aggiornamento: agosto 2016
Come dotnet team ha pubblicato le novità di C # 7.0 e da un commento di Mads Torgensen :
Proprietà dell'estensione: abbiamo avuto un stagista (geniale!) Implementarlo durante l'estate come esperimento, insieme ad altri tipi di membri dell'estensione. Rimaniamo interessati a questo, ma è un grande cambiamento e dobbiamo sentirci sicuri che ne valga la pena.
Sembra che le proprietà di estensione e altri membri siano ancora buoni candidati da includere in una versione futura di Roslyn, ma forse non quella 7.0.
Aggiornamento: maggio 2017
I membri dell'estensione sono stati chiusi come duplicati dell'estensione di tutto ciò che è stato chiuso. La discussione principale era in effetti sull'estensibilità del tipo in senso lato. La funzione è ora tracciata qui come proposta ed è stata rimossa dalla pietra miliare 7.0 .
Aggiornamento: agosto 2017 - Funzionalità proposta di C # 8.0
Mentre rimane ancora solo una funzionalità proposta , ora abbiamo una visione più chiara di quale sarebbe la sua sintassi. Tieni presente che questa sarà la nuova sintassi anche per i metodi di estensione:
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;
Simile alle classi parziali, ma compilato come classe / tipo separato in un assembly diverso. Nota che potrai anche aggiungere membri e operatori statici in questo modo. Come menzionato nel podcast di Mads Torgensen , l'estensione non avrà alcun stato (quindi non può aggiungere membri di istanze private alla classe), il che significa che non sarà possibile aggiungere dati di istanze private collegati all'istanza . Il motivo invocato per questo è che implicherebbe la gestione dei dizionari interni e potrebbe essere difficile (gestione della memoria, ecc ...). Per questo, puoi ancora usare la tecnica TypeDescriptor
/ ConditionalWeakTable
descritta in precedenza e con l'estensione della proprietà, la nasconde sotto una bella proprietà.
La sintassi è ancora soggetta a modifiche in quanto implica questo problema . Ad esempio, extends
potrebbe essere sostituito dal for
quale alcuni potrebbero sentirsi più naturali e meno correlati a Java.
Aggiornamento dicembre 2018 - Ruoli, estensioni e membri dell'interfaccia statica
L'estensione di tutto non è arrivata a C # 8.0, a causa di alcuni svantaggi spiegati come la fine di questo ticket GitHub . Quindi, c'è stata un'esplorazione per migliorare il design. Qui , Mads Torgensen spiega quali sono i ruoli e le estensioni e come differiscono:
I ruoli consentono l'implementazione delle interfacce su valori specifici di un determinato tipo. Le estensioni consentono di implementare le interfacce su tutti i valori di un determinato tipo, all'interno di una specifica regione di codice.
Può essere visto in una divisione della proposta precedente in due casi d'uso. La nuova sintassi per l'estensione sarebbe così:
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));
}
}
}
allora saresti in grado di fare questo:
foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
WriteLine($"{e.Current:X}");
}
E per un'interfaccia statica :
public interface IMonoid<T> where T : IMonoid<T>
{
static T operator +(T t1, T t2);
static T Zero { get; }
}
Aggiungere una proprietà extension su int
e trattare il int
come IMonoid<int>
:
public extension IntMonoid of int : IMonoid<int>
{
public static int Zero => 0;
}