C# return a variable as read only from get; set;

徘徊边缘 提交于 2019-12-04 08:15:02

问题


I swear I have seen an example of this but have been googling for a bit and can not find it.

I have a class that has a reference to an object and need to have a GET; method for it. My problem is that I do not want anyone to be able to fiddle with it, i.e. I want them to get a read only version of it, (note I need to be able to alter it from within my class).

Thanks


回答1:


No, there's no way of doing this. For instance, if you return a List<string> (and it's not immutable) then callers will be able to add entries.

The normal way round this is to return an immutable wrapper, e.g. ReadOnlyCollection<T>.

For other mutable types, you may need to clone the value before returning it.

Note that just returning an immutable interface view (e.g. returning IEnumerable<T> instead of List<T>) won't stop a caller from casting back to the mutable type and mutating.

EDIT: Note that apart from anything else, this kind of concern is one of the reasons why immutable types make it easier to reason about code :)




回答2:


Return a reference to a stripped-down interface:

 interface IFoo
   string Bar { get; }

 class ClassWithGet
   public IFoo GetFoo(...);



回答3:


This isn't possible. Get and set accessors to reference types get and set the reference to the object. You can prevent changes to the reference by using a private (or internal) setter, but you cannot prevent changes to the object itself if it's exposed by a getter.




回答4:


If the object isn't too complicated/extensive then write an wrapper around it.

for example:

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;
         }
    }
}

So now all you do is give your client code an instance of the AWrapper class so that they may only use what you allow them to see.

this may get a bit complicated and may not scale well if your base class is not set in stone, but for most simple situation it may just do the trick. I think this is called a facade pattern(but don't quote me on that =) )




回答5:


Your question reads like you're looking for:

public PropertyName { get; private set; }

But then, given the answers so far I'm not sure I'm interpreting your question correctly. Besides, who am I to question Jon Skeet? :)




回答6:


i agree with ReadOnlyCollection

See my simple code:

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

}

ReadOnlyCollection dosen't has Add method so user cant add properties to it.BUT ther is no warranty that if user can modify objects by calling their methods....




回答7:


I have faced this problem in a certain way. I have a CategoryViewModel class, which have a property Category that I want private read-only :

public CategoryViewModel
{
    private Category { get; }

}

In fact, I want it to be exported as read-only to other class. However I can't do such thing. In my case (maybe it will help some other guys), I want to add it to a repository. The only way that I've found is to have a function with the repository as param 1, and an Action as param 2 :

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

Like that, from elsewhere, I can do such thing :

 categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));

This can help other to expose there property only for certains cases and can manage them.



来源:https://stackoverflow.com/questions/939563/c-sharp-return-a-variable-as-read-only-from-get-set

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!