IEnumerable<T>
をクラスのプロパティとして公開すると、クラスのユーザーによって突然変異が起こる可能性はありますか?そうであれば、公開されたプロパティの型を保持しながら突然変異から保護する最善の方法はIEnumerable<T>
です?IEnumerableをプロパティに公開するのは安全ですか?
答えて
これは返品内容によって異なります。変更可能な文字を返すと(List<string>
)、クライアントはそれを実際にList<string>
にキャストして変異させることができます。
あなたのデータを保護する方法は、あなたが始めなければならないものによって決まります。 IList<T>
が始まるとすれば、ReadOnlyCollection<T>
は良いラッパークラスです。効果的にイテレータでコレクションをラップ
public IEnumerable<string> Names
{
get { return names.Select(x => x); }
}
:あなたのクライアントはIList<T>
またはICollection<T>
を実装し、戻り値の恩恵を受けない場合
、あなたはいつものような何かを行うことができます。 (LINQを使ってソースを非表示にする方法はいろいろありますが、どのオペレータがソースを非表示にしていないかは記載されていませんが、Skip(0)
を呼び出すとはMicrosoftの実装でソースを隠しますそのように文書化されています)
Select
間違いなくはソースを非表示にします。
いつものように、Jon Skeetは良い答えを提供します。私はちょうど別のデータ収集の種類は、プログラムのセキュリティのために使用するためのものではないことを追加する必要があります。完全に信頼できる環境で動作させると、内部に隠されたものを見つけるためにオブジェクトに深く掘り下げることができます。実際にコレクションを変更から保護する必要がある場合は、アプリケーションセキュリティメカニズムを使用する必要があります。 –
コレクションを元のタイプにキャストバックすることができます。コレクションが変更可能な場合は、コレクションを変更することができます。
オリジナルの変更の可能性を回避する方法の1つは、リストのコピーです。
クローンを作ることは可能ですが、それは本当に「最良の方法」ですか?たぶんそれは時々あるが時にはそうではない。 –
大きなコレクションの場合、コピーを返すのは高価です。コピーのセマンティクスが本当に必要な場合を除き、私はJonSkeetのようなラッパーを推奨します。 – CodesInChaos
@Al、@CodeInChaos - 公正なポイント...回答が修正されました。 – Oded
ユーザーがコレクションクラスにキャストし直すことができるため、公開している可能性があります。
collection.Select(x => x)
と、これは新しいIEnumerableを私は基本的な接続でmonkeyingから受信者を防ぐために、イテレータでのIEnumerableをラップしないようにお勧めしているが、コレクション
私はこれが好きです。コレクションが参照型である場合、要素のメンバーはまだ変更可能ですが、リストまたは配列にスラッシングして列挙型のカーディナリティと順序を変更しても、元のコレクションには影響しないことを理解してください。 – KeithS
にキャストすることはできません作成されます。プロパティの戻り値の型がIEnumerable<T>
ある場合は、WrappedEnumerable<T>
からIEnumerable<T>
への型変換は構造をボックスと動作とパフォーマンスは、クラスのものと一致するだろう
public struct WrappedEnumerable<T> : IEnumerable<T>
{
IEnumerable<T> _dataSource;
public WrappedEnumerable(IEnumerable<T> dataSource)
{
_dataSource = dataSource;
}
public IEnumerator<T> GetEnumerator()
{
return _dataSource.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((System.Collections.IEnumerable)_dataSource).GetEnumerator();
}
}
:私の傾きは次のようにラッパーものを使用することです。しかし、プロパティが戻り値のタイプとしてWrappedEnumerable<T>
と定義されていた場合、呼び出しコードが戻り値をタイプWrappedEnumerable<T>
(おそらくvar myKeys = myCollection.Keys;
のような結果の可能性が高い)に割り当てる場合にボクシングステップを保存することが可能です)、または単に "foreach"ループでプロパティを直接使用します。 GetEnumerator()
によって返された列挙子が構造体である場合、それはどんな場合でもボックス化されなければならないことに注意してください。
クラスではなく構造体を使用することのパフォーマンス上の利点は、通常はごくわずかです。概念的には、構造体を使用すると、プロパティが新しいヒープオブジェクトインスタンスを作成しないという一般的な推奨に適合します。既存のヒープオブジェクトへの参照だけを含む新しい構造体インスタンスを作成することは非常に安価です。ここで定義されている構造体を使用することの最大の欠点は、呼び出しコードに返されるものの動作をロックし、単にIEnumerable<T>
を返すと他のアプローチが可能になることです。
public struct FancyWrappedEnumerable<TItems,TEnumerator,TDataSource> : IEnumerable<TItems> where TEnumerator : IEnumerator<TItems>
{
TDataSource _dataSource;
Func<TDataSource,TEnumerator> _convertor;
public FancyWrappedEnumerable(TDataSource dataSource, Func<TDataSource, TEnumerator> convertor)
{
_dataSource = dataSource;
_convertor = convertor;
}
public TEnumerator GetEnumerator()
{
return _convertor(_dataSource);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _convertor(_dataSource);
}
}
:つのタイプなどを使用した場合、いくつかのケースでは、任意のボクシングの必要性を排除し、C#とvb.net foreach
ループでダックタイピングの最適化を利用することが可能であること
も注意convertor
デリゲートは静的デリゲートになる可能性があるため、実行時に(クラスの初期化以外の)ヒープオブジェクトの作成は必要ありません。このアプローチを使用して、List<int>
から列挙子を返す場合は、戻り値の型はFancyWrappedEnumerable<int, List<int>.Enumerator, List>
になります。おそらく呼び出し元がforeach
ループまたはvar
宣言で直接プロパティを使用した場合はおそらく合理的ですが、呼び出し元がvar
を使用できない方法で型の格納場所を宣言したいと思っていた場合は、
- 1. 公開情報を公開ディレクトリに保存するのは安全ですか?
- 2. Azureに安全に公開する
- 3. 例外のメッセージを公開するのは安全ですか?
- 4. AWS Cognito IDを公開するのは安全ですか?
- 5. 私のコードを安全にする方法は? - 非公開vs.公開
- 6. Visual Studio 2010のFTP公開は安全ですか?
- 7. 公開SSH rsaキーをmongodbに保存するのは安全ですか?
- 8. コードでgoogleのショートカットのapiキーを公開するのは安全ですか?
- 9. MongoDB:文書のIDを「公開」しても安全ですか?
- 10. Javascriptに「安全でない公開」がありますか?
- 11. このスクリプトを公開するのは安全ですか?初心者質問
- 12. ファブリックAPIキーを公開しても安全ですか?
- 13. 公開鍵/秘密鍵を安全にデータベースに格納する
- 14. ライブストリームをAdobe Flash Media Serverに安全に公開する方法
- 15. HTML5プロパティのcontenteditableは安全ですか?
- 16. 安全でないArrayListを公開するマルチスレッドライブラリ
- 17. 安全に配列要素を公開する
- 18. wso2 api manager安全な公開API
- 19. APIを開発者に安全に公開するにはどうすればよいですか?
- 20. 安全なゲートウェイを介してapiを公開する
- 21. 公共のウェブサイトでp12をpemに変換するのは安全ですか?
- 22. cサービス/ cppサービスを簡単かつ安全に公開する方法
- 23. PHP - 公開された可視性は安全性が低いですか?
- 24. djangoで最も安全な方法でユーザーパスワードを公開するにはどうすればいいですか?
- 25. textField.textを安全にアンラップしてプロパティに安全に保存する方法
- 26. exeファイルでpdbを公開するのはどれくらい安全ですか?
- 27. AzureのFTP展開はどのように安全ですか?
- 28. pthread_cond_waitは完全に安全ですか?
- 29. _bstr_t comプロパティにLPCTSTRを代入するのは安全ですか?
- 30. ブーストメッセージキューのスレッドは安全でプロセスは安全ですか?
コレクションをプロパティとして使用する際には注意が必要です。このデザインガイドのリンクをMSDN から確認してください。https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/guidelines-for-collections –