現時点では、Roslynコンパイラーはそのままではまだサポートされていません...
これまで、拡張プロパティは、以前のバージョンのC#標準に含めることができるほど価値があるとは見なされていませんでした。C#7とC#8.0はこれをプロポーザルチャンピオンと見なしていますが、まだリリースされていません。何よりも、実装がすでに存在していても、最初から正しいものにしたいからです。
しかし、それは...
ある延長部材の項目がでC#7作品リスト、それは近い将来にサポートすることができるようにします。拡張プロパティの現在のステータスは、Githubの関連アイテムの下にあります。
ただし、特にプロパティと静的クラス、さらにはフィールドに焦点を当てた「すべてを拡張する」というさらに有望なトピックがあります。
さらに、回避策を使用できます
この記事で指定されTypeDescriptor
ているように、実行時にオブジェクトインスタンスに属性をアタッチする機能を使用できます。ただし、標準プロパティの構文は使用していません。クラスにデータを格納する拡張メソッドのエイリアスの
ように拡張プロパティを定義する可能性を追加するだけの構文糖とは少し異なります。
string Data(this MyClass instance)
string GetData(this MyClass instance)
C#7がすべての機能を備えた拡張機能(プロパティとフィールド)を提供することを願っていますが、その時点では時間だけがわかります。
そして、明日のソフトウェアがコミュニティから来るので、気軽に貢献してください。
更新:2016年8月
dotnetチームがC#7.0の新機能とMads Torgensenのコメントを公開したとき:
エクステンションのプロパティ:(すばらしい!)インターンに、他の種類のエクステンションメンバーとともに、夏の間にそれらを実験として実装しました。私たちはこれに興味を持っていますが、それは大きな変化であり、それが価値があると確信する必要があります。
拡張プロパティや他のメンバーは、Roslynの将来のリリースに含まれる候補としてはまだ良いようですが、7.0には含まれない可能性があります。
更新:2017年5月
エクステンションのメンバーは、エクステンションの複製としてクローズされています。主な議論は、実際には広い意味での型の拡張性についてでした。この機能は提案としてここで追跡され、 7.0マイルストーンから削除されました。
更新:2017年8月-C#8.0提案機能
これはまだ提案された機能にすぎませんが、構文がどうなるかをより明確に把握できるようになりました。これも拡張メソッドの新しい構文になることに注意してください。
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;
部分クラスに似ていますが、別のアセンブリで別のクラス/タイプとしてコンパイルされます。この方法で静的メンバーと演算子を追加することもできます。Mads Torgensenポッドキャストで述べたように、拡張機能には状態がないため(クラスにプライベートインスタンスメンバーを追加できません)、インスタンスにリンクされたプライベートインスタンスデータを追加できません。そのために呼び出される理由は、内部で辞書を管理することを意味し、困難である可能性があります(メモリ管理など)。このため、以前に説明したTypeDescriptor
/ ConditionalWeakTable
手法を使用でき、プロパティ拡張を使用して、素敵なプロパティの下にそれを非表示にします。
この問題を暗示するため、構文は変更される可能性があります。たとえば、一部はより自然でJava関連性が低いと感じる可能性があるものにextends
置き換えることができますfor
。
2018年12月の更新-ロール、拡張機能、静的インターフェースメンバー
このGitHubチケットの終わりとして説明されているいくつかの欠点のため、すべてを拡張してもC#8.0に到達しませんでした。したがって、デザインを改善するための調査がありました。ここでは、Mads Torgensenが役割と拡張機能とは何か、およびそれらの違いについて説明します。
ロールを使用すると、特定のタイプの特定の値にインターフェースを実装できます。拡張機能により、コードの特定の領域内で、特定のタイプのすべての値にインターフェースを実装できます。
これは、2つのユースケースで以前の提案の分割で見ることができます。拡張の新しい構文は次のようになります。
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));
}
}
}
その後、これを行うことができます:
foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
WriteLine($"{e.Current:X}");
}
そして静的インターフェースの場合:
public interface IMonoid<T> where T : IMonoid<T>
{
static T operator +(T t1, T t2);
static T Zero { get; }
}
に拡張プロパティを追加しint
、int
として扱いますIMonoid<int>
。
public extension IntMonoid of int : IMonoid<int>
{
public static int Zero => 0;
}