2009-06-02 9 views
33

私はこれの例を見たことがあるが、ちょっとグーグルで見つけられないと誓っている。C#はgetから読み込み専用として変数を返します。セット;

私は、オブジェクトへの参照を持ち、GETが必要なクラスを持っています。それのための方法。私の問題は、他の誰かがそれを試すことができないようにしたいということです。つまり、私はそれらの読み込み専用バージョンを取得したいと思います。(クラス内から変更できる必要があります。

おかげ

+1

私は何人の人がその質問を誤解しているのに驚いています。ジョン・スケートとアントン・ゴゴレフはそれを正しくしました。 –

+1

私は誤解しているとは思っていませんでしたが、まだ投票してしまったのですが、まあ – ChrisF

+0

それはトリックの質問でした:) –

答えて

51

いいえ、これを行う方法はありません。たとえば、List<string>を返すと(不変ではない)、を呼び出すとにエントリを追加できるようになります。

通常の方法で、これは不変のラッパーを返すことです。 ReadOnlyCollection<T>

他の可変型の場合、値を返す前に値を複製する必要があります。

List<T>の代わりにIEnumerable<T>を返すなど、不変なインターフェイスビューを返すだけでは、呼び出し元が変更可能な型にキャストして変異を起こすことはなくなります。

EDIT:他の何かからそれを離れて注意、関心のこの種は不変タイプは、それが簡単にコードを推論するために作る理由の一つです:)

+2

クローニングのための+1(私は既に+1した) –

+2

最初にそれはできないと言うクローニング溶液に添加する。また、おそらくクローニングはC#の新しいアイデアですが、C++で長い間そこにいました。また、厳密にクローニングするわけではありません。内部データのコピーを作成し、元のデータではなくこのコピーを返すことです。コピーは元のデータと同じである必要はありません。 – mayu

6

戻る削ぎ落としたインターフェイスへの参照:

interface IFoo 
    string Bar { get; } 

class ClassWithGet 
    public IFoo GetFoo(...); 
+1

理想的には、それがキャストバックできないようにIFooの 'private'または' internal'の実装を含みます;) – jerryjvl

+0

Humはインタフェースが内部または私的でない場合、アクセスできない型を持つPublicメンバを返すことができるようになりました。これはコンパイルされません: "一貫性のないアクセシビリティ:フィールドタイプ...フィールドよりもアクセスしにくいです..." –

3

これは不可能です。参照型へのアクセサーの取得と設定オブジェクトへの参照の取得と設定。プライベート(または内部)セッターを使用して参照の変更を防ぐことはできますが、ゲッターで公開されている場合はオブジェクト自体の変更を防ぐことはできません。

+0

はい、可能です。データのコピーを返すことができます。 – mayu

3

オブジェクトがあまり複雑すぎない場合は、そのオブジェクトの周りにラッパーを作成します。例えば

class A { 
    public string strField = 'string'; 
    public int intField = 10; 
} 

class AWrapper { 
    private A _aObj; 

    public AWrapper(A aobj) { 
     _aObj = A; 
    } 

    public string strField { 
     get { 
      return _aObj.strField; 
     } 
    } 

    public int intField { 
     get { 
      return _aObj.intField; 
     } 
    } 
} 

だから今あなたがすべてのは、彼らが唯一のあなたがそれらを見ることができるように何を使用できるように、クライアントコードにAWrapperクラスのインスタンスを与えることです。

基本クラスが石で設定されていない場合、これは少し複雑になり、スケールがうまくいかないかもしれませんが、ほとんどの単純な状況ではちょっとしたことがあるかもしれません。私は、これはFacadeパターンと呼ばれていると思います(ただし=その上で私を引用しないでください))

0

私はReadOnlyCollection

に同意し、私の単純なコードを参照してください:

private List<Device> _devices; 
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices 
{ 
get 
{ 
return (_devices.AsReadOnly()); 
} 

}

ReadOnlyCollectionをユーザーがメソッドを呼び出すことによってオブジェクトを変更できる場合は、それは保証されません。

1

あなたが探しているようにあなたの質問:読み取り

public PropertyName { get; private set; } 

しかし、その後、回答を与えられたこれまでのところ、私は私が正しくあなたの質問を解釈してるかわかりません。また、誰が私はジョン・スケートに質問するのですか? :)

+0

これは、割り当てられないため読み込み専用の参照を返しますが、プロパティは読み込み専用ではないため、オブジェクトを編集することはできます – DCShannon

0

私はこの問題に一定の方法で直面しています。 私はプライベート読み取り専用のプロパティたいカテゴリ持っCategoryViewModelクラス、持っている:実際には

public CategoryViewModel 
{ 
    private Category { get; } 

} 

を、私はそれが読み取り専用の他のクラスにとしてエクスポートすることにしたいです。しかし、私はそのようなことをすることはできません。 私の場合(多分それは他の人に役立つかもしれません)、リポジトリに追加したいのですが。

categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c)); 
:私はそのようなことを行うことができ、他の場所から、そのような

public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action) 
{ 
    action(repo, Category); 
} 

:私が見つけた唯一の方法は、PARAM 1としてリポジトリを持つ関数、およびパラメータ2などのアクションを持つことです

これは、特定のケースに対してのみプロパティを公開し、管理することができる他の人に役立ちます。

関連する問題