PInvokeをラップするプロパティのget関数に多くのコードを配置するのは悪い習慣ですか?
-
11-07-2019 - |
質問
わかりやすいタイトル。説明させてください。
構造体の配列をマーシャリングし、クラスの配列に変換する必要があります(レガシー互換性)。たとえば
public class InnerClass {}
public class OuterClass { private InnerClass[] innerClasses; }
public struct InnerStruct {
// Data
}
private static buildInnerClass( InnerStruct i );
public struct OuterStruct {
private int _numInnerStructs;
private IntPtr _innerStructs;
// Other members
public InnerClass[] InnerClasses {
get {
InnerClass[] ret = new InnerClass[_numInnerStructs];
var structSize = Marshal.SizeOf(typeof(InnerStruct));
var ptr = _innerStructs;
for (int i = 0; i < _numInnerStructs; i++)
{
InnerStruct innerStruct = (InnerStruct)Marshal.PtrToStructure(
ptr, typeof(InnerStruct));
ret[i] = buildInnerClass(innerStruct);
ptr = (IntPtr)((int)ptr + structSize);
}
return ret;
}
}
}
解決
真空で見た場合、このプラクティスに本質的に問題はありません。ただし、それに注意する必要があります...
- プロパティゲッターは、例外はほとんどありませんが、「高価」ではありません。 (つまり、実行するために多くのCPUサイクルやリソースを消費すべきではありません)
- プロパティゲッターは決して副作用を引き起こさないはずです。たとえば、PInvokeコードが何らかの種類の新しいハンドルを取得する場合、ゲッターではなく関数である必要があります。
一般に、プロパティは、コンシューマが値をキャッシュするよりもプロパティを再度呼び出すよりも、もしあるとしても多くの理由を持たないように書かれるべきであることに留意してください。責任ある開発者があなたの財産でその慣行に従うことができれば、あなたは正しい軌道に乗っています。
他のヒント
プロパティのゲッターは可能な限り最小限にする必要があります。あなたの場合、通常の方法を使用する方がおそらく良いでしょう。特に、プロパティから配列を返すことも悪い考えです。
そのコードをPInvoke構造体に配置することは、通常の構造体に配置することより悪くありません。 PInvokeの目的では、構造体のフィールドのみが考慮されるため、プロパティコードは機能しません。コードがその特定のプロパティにアクセスする場合にのみ関連します。
所属していません StackOverflow