構造体に拡張メソッドを追加できますか?構造体の拡張メソッド
答えて
はい、構造体に拡張メソッドを追加できます。拡張メソッドの定義に従って、簡単に達成できます。以下はintの拡張メソッドの例です
namespace ExtensionMethods
{
public static class IntExtensions
{
public static bool IsGreaterEqualThan(this int i, int value)
{
return i >= value;
}
}
}
しかし、構造体が拡張メソッドBY VALUEに渡されるので、これに注意してください(構造体がしたいように)。したがって、構造体を返さない限り(そしてそれを元の構造体に渡して、それ自身に再割り当てするなどして)、拡張メソッドの構造体に加えた変更はすべて失われます。 構造体に対して拡張メソッドを実行し、参照渡しする方法はありません(C#)。 – BrainSlugs83
構造体であり、SerializableとComVisibleとTypeConverterで装飾されたSystem.Drawing.Rectangleを拡張できないようです。 – zionpi
構造体に拡張メソッドを追加することは可能ですが、重要な注意点があります。通常の構造体メソッドのメソッドはthis
をref
のパラメータとして受け付けますが、C#ではこれを行う拡張メソッドの定義を許可しません。 this
を変更するstructメソッドは、コンパイラによって構造体メソッドが読み込み専用構造体で呼び出され、this
が値渡しされるため、やや危険ですが、それらが確実に存在するように注意すると便利な場合もあります適切なコンテキストでのみ使用されます。
なお、vb.netでは、拡張メソッドがByRef
というパラメータとして、this
を受け入れることができます。これは、クラス、構造体、または不明なカテゴリのジェネリックであるかどうかに関係なく適用されます。これは、インタフェースが構造体によって実装される場合に役立ちます。例えば、型List<string>.Enumerator
の変数に対して、IEnumerator<string>
型のthis
パラメータを受け取るか、またはIEnumerator<string>
に制限された汎用の値this
を引数とする拡張メソッドを呼び出すと、メソッドが列挙子を前進しようとすると、メソッドが返ってくると、どんな進歩も取り消されます。ただし、参照によって制約付きジェネリックを取る拡張メソッド(vb.netで可能)は、必要に応じて動作します。
C#で1つ使用する例は何ですか? 'public static Rect CreateRectFromPercents(このRect rect)'などは動作しません。 – MichaelTaylor3D
@ MichaelTaylor3D: 'Rect'とは何ですか?あなたは 'System.Drawing.Rectangle'やカスタムタイプを意味しますか? – supercat
私のAPIの一部である構造体です。私は例として使っていました。 apiは私にそれを直接変更させないようにするので、私は拡張メソッドを使うことを望んでいました。私は構造体の可能性を読んだが、私はまだ例を見てhavnt。あなたの説明は私が見つけることができる最も近いです。 – MichaelTaylor3D
はい、構造体/値型に対して拡張メソッドを定義できます。ただし、参照型の拡張メソッドと同じ動作をしません。
たとえば、次のC#コードのGetA()拡張メソッドは、構造体への参照ではなく、コピーの構造体を受け取ります。つまり、構造体のC#拡張メソッドは元の構造体の内容を変更できません。
public static class TestStructExtensionMethods {
public struct FooStruct {
public int a;
}
public static int GetA(this FooStruct st) {
return st.a;
}
}
構造体の内容を変更するには、struct paramaterを "ref"として宣言する必要があります。ただし、C#では "このref"は許可されていません。
' This is efficient, because it is handed a reference to the struct
<Extension()> _
Public Sub GetA(ByRef [me] As FooStruct) As Integer
Return [me].a
End Sub
' It is possible to change the struct fields, because we have a ref
<Extension()> _
Public Sub SetA(ByRef [me] As FooStruct, newval As Integer)
[me].a = newval
End Sub
:私たちができる最善のような静的な非拡張メソッドである:それは、元の構造体を修正することができるように
VB.NETで
// this works, but is inefficient, because it copies the whole FooStruct
// just to return a
public static int GetA(ref FooStruct st) {
return st.a;
}
、あなたは、ByRefの構造体の拡張メソッドとしてこれを作成することができます
そのVB。NETは拡張メソッドが 'ref'によって構造体を受け入れることを可能にしますが、VBは' ref'で渡せないものを静かにコピーし、元のものの代わりにコピーを渡すという事実のためには良いことです。 VB.NETにそうしないよう指示する方法があれば(そのコードはコンパイルを拒否しなければならない)、そのような拡張メソッドは、 'this'を変更するstructインスタンスメソッドより意味的に優れています。私は、MSがコンパイラが生成した一時構造上で呼び出し可能かどうかを示す方法が何であるかを示す手段を提供していないのはなぜか分かりません。 – supercat
"...しかし、VBが自動的にrefで渡すことができないものをコピーし、オリジナルの代わりにコピーを渡すということは、VBがいつそうするのでしょうか? - "byref"はC#で "ref"と同じILコードにコンパイルされています - 私の理解は、.NETでrefで渡すことができることです - コピーされるのは値の型だけです彼らはrefによって渡されません)。 – BrainSlugs83
@ BrainSlugs83:VB.netで参照によって読み取り/書き込みプロパティを渡してみてください。そのプロパティは単に変数ではなくゲッター関数の戻り値です。参照渡しは機能しません。 C#はそれを許可しません。代わりに、VBは値をコピーし、* copy *を参照渡しで参照渡しを行います。関数が返ってくると、プロパティを新しい値に設定します。 LoDに従って構造体を変更することはできませんが、サブオブジェクトや変更可能な値の型が関わっている場合は、半驚くべき方法で破損する可能性があります。 – cHao
将来のGoogle社員(およびBingers)のために、構造体を拡張するためのコードがいくつかあります。この例では、値をdouble
タイプに変換します。この後
public static class ExtensionMethods {
public static double ToDouble<T>(this T value) where T : struct {
return Convert.ToDouble(value);
}
}
あなたがToString()
を使用するようにあなたはToDouble()
を使用することができます。オーバーフローなどのコンバージョンアイテムには注意してください。
- 1. 構造体の拡張メソッド
- 2. 構造体配列を拡張する
- 3. Goを構造体に拡張する
- 4. 他の構造体内にある構造体を拡張する
- 5. スウィフトプロトコル拡張(構造)タイプ
- 6. Doubleを自分の構造体内で拡張する
- 7. Swift構造体の拡張を作成する方法JoinedSequence?
- 8. 構造体のクラス拡張を作成するには?
- 9. 継承クラスで構造体を拡張する
- 10. エアネイティブ拡張から構造体を返す
- 11. 構造体からncurses拡張文字を使用する
- 12. 構造体/ドキュメントをループ内に拡張する
- 13. Swift構造体拡張子初期化子を追加
- 14. java - tree構造体メソッド
- 15. 拡張クラス内の拡張メソッド自体を使用して
- 16. 拡張可能ハンドラ/プラグインアーキテクチャのRuby構造
- 17. C構造体内の構造体内部の構造体
- 18. Python拡張モジュールパッケージ構造(名前空間)
- 19. Visual Studio 2015ファイル構造拡張子
- 20. C++の構造体内の構造体
- 21. 構造体のメンバをRustの同じ構造体のメソッドに渡す
- 22. 構造体のメソッドの構造体のポインタ値を変更します。
- 23. Kotlin拡張メソッドの構成方法
- 24. 構造体内の構造体
- 25. 構造体の配列 - 構造体?
- 26. 一般的な配列型指定の構造体を拡張する
- 27. 構造体変数と構造体メンバ
- 28. sizeof構造体内構造体
- 29. 構造体をIDispatchメソッドに渡す
- 30. LINQの拡張メソッド - GetYearWeekFormat拡張
構造体に拡張メソッドを追加しようとしましたか?あなたはそれらに答えを見つけるときに質問を削除してはならないことに注意してください、他の人は同じことについて疑問に思うかもしれません。そして、はい、それらを宣言することはできますが、構造体の変更は、それが動作しないことを期待しない限り、期待通りに機能しません。 –
ええ、私は試してみましたが、うまくいきませんでした。 –
ありがとう、私の欠陥 –