views:

120

answers:

3

I am writing a function that returns a reference to an object of some encapsulated data structure and I want nobody to be able to change the object using that reference, is it possible to do this in c#?

+1  A: 

The only way I see is to create two interfaces for this type. One interface just being read only. Then the method just returns an instance of this readonly interface.

schoetbi
And the caller can cast to the interface that is not readonly.
Oded
But nobody would to these kind of things. :-) Wrapper is better for safety. So I also like your version.
schoetbi
So many catch-phrases about assumptions, so little character space...
Allon Guralnek
@Oded, or use reflection to read even private members. IMHO .Net misses both a proper immutability and total accessibility management.
Dykam
@Dykam, accessibility is suppose to help you, not protect you. it's there to make writing code easier but doesn't serve any actual security issues. If reflection couldn't modify private variables then there would be tons of times where you would curse the designers of .NET for thinking they know better than their users.
tster
@tster, I know the reasoning, but I've encountered some situations where I cursed .Net for not having a solid security. To be completely save, you need to fire up and completely separate AppDomain. I, personally, would have liked some attribute marking members as not reflectable/hidden from reflection.
Dykam
+8  A: 

If the object that you are returning is immutable, that will work fine.

If not, you can return a wrapper object that only exposes read-only properties.

Oded
+1 The only issue being if somewhere they already have references to the internal structures of the immutable type.
Matthew Abbott
A: 

I don't think there is any built-in way. C# doesn't seem to have the same support for const-correctness that C++ does. You can make the internal members read-only, and that will be a start. But there is more to it than that.

You would make all member functions of your class non-mutator functions, and make all data members properties w/ private setters. When implementing the getters for the properties, copy any classes that come back, and return a new instance, rather than returning a reference to a private member.

class SomeClass
{
    public void SomeFunctionThatDoesNotModifyState()
    {
    }

    public int SomeProperty
    {
        get
        {
            return someMember; // This is by-value, so no worries
        }
    }

    public SomeOtherClass SomeOtherProperty
    {
        get
        {
            return new SomeOtherClass(someOtherMember);
        }
    }
}

class SomeOtherClass { // .... }

You will have to be very careful that the implementation of SomeOtherClass does a deep copy when you call the copy constructor.

Even after all this, you can't 100% guarantee that someone won't modify your object, because the user can hack into any object via reflections.

Merlyn Morgan-Graham