Sign in to follow this  
xsirxx

[.net] A simple question about get/set.... C# .NET

Recommended Posts

ok here is a newb question about the new(in C#, im a C++ programmer) get/sets... say I have: class SomeFoo; class Foo { private SomeFoo sfFOO = new SomeFoo(); public SomeFoo SomeFOO{ get{ return sfFOO ; } set{ sfFOO = value; } } } How do I make sure that when I return sfFOO that they can only SEE it and not change it, sorta like static was used in C++? I know its passing back a reference but I want it to send back a value, or rather a reference but not have it copy or clone and take up double the memory.... So to make things clear, I want them to be able to set it and see it easily but not be able to change it outside of the Foo class. Sorry for the newb question but I cant seem to find anything on the get/set stuff that dives further in.. Thanks, Brad

Share this post


Link to post
Share on other sites
Sorry, I'll not be answering you but I'm having the exact same question here!

I fear that no such protection exists as const member function and const function parameters do not exist in C#. Maybe they destroyed the whole "const object" concept? From my point of view that'd be big a mistake.

Anyways, I'm still curious about the actual answer.

Share this post


Link to post
Share on other sites
This MSDN guy says :

Quote:
Original text by Eric Gunnerson
My number one biggest desire in C#, or complaint (if you choose)... Are we ever going to see const methods, objects and properties? I'm one of those who basically think languages we should actually be delimiting non-const items, and having everything default to const, but even though there are work-arounds, not having a const specifier I think encourages people (like me) to be lazy and write really dangerous code!


I think that this confirms the fact that C# has absolutely no const objects/references mechanism. A documentation page explaining this would still be nice.

Share this post


Link to post
Share on other sites
Yea that is very scary. I was just going through writing some code(just started in C#) and am having issues with everything being a reference. It just seems so dangerous when you have to work with other programmers accidently doing something or even yourself making a 3am mistake.

So I would love a way that people can see what I have in my object yet not be able to change the reference in the object itself. The only way I can think of doing it would be to create a new reference and pack it with a clone... which just seems like a massive waste of time and space.

Share this post


Link to post
Share on other sites
You're overlooking the fact that you have multiple references to the same instance.

The reference returned by the get property is a separate reference to the same instance. If you change the retrieved reference to something else, the original reference inside the class will still point to the original instance.

In your example, I could retrieve a reference to sfFoo, and set that reference to null. However, the reference to sfFoo inside the Foo class is still intact.

In my opinion this makes the const keyword unnecessary.

Additionally, if you don't want the user to alter sfFoo itself by calling member functions, then you shouldn't allow them to retrieve it in the first place. Alternatively, you could also make SomeFoo a struct, which is a value type. Then they'll receive a copy of sfFoo, rather than a reference to it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Alpha_ProgDes
I thought we're supposed to be using properties as opposed to get/set functions....?


I don't understand what you're trying to say here, especially considering that the example described in this thread does use properties...

Share this post


Link to post
Share on other sites
The problem comes when sfFOO has public methods which you don't want people to call when they access it through the property. Doesn't change the reference, still effects the object.

There's been a few times where I've run across this design desire but I've never much run into the practical problem where I or others modify it. Another thing to keep in mind is that often these sort of patterns occur in a module. Using internal rather than public on SomeFoo's methods will still allow you the access you need while mitigating the possibility for unintended use in such scenarios.

Share this post


Link to post
Share on other sites
pros and cons of good and bad programming aside you could make set private, thus:

class SomeFoo;
class Foo
{
private SomeFoo sfFOO = new SomeFoo();
public SomeFoo SomeFOO{ get{ return sfFOO ; } private set{ sfFOO = value; } }
}

Share this post


Link to post
Share on other sites
In java the solution was to create objects that can't be modfyed in any way, to get a modified version the method used to change a value returns clone of it that has the desired fields changed

In c# you can also use structs to accomplish the same thing, structs objects are just like classes objects except anytime you try to copy its reference it clones its self and copys the reference to the new object


//struct, just like a class
struct Foo{
public Foo(){
num=5;
}
public int num;
}

//make new object from Foo
foo1 = new Foo();

//foo1 is cloned and foo2 gets a reference to the clone, not foo1
foo2 =foo1;

//this will not change foo1's num
foo2.num=45;

//at the end foo1.num == 5 and foo2.num == 45


Share this post


Link to post
Share on other sites
Quote:
Original post by gharen2
You're overlooking the fact that you have multiple references to the same instance.

The reference returned by the get property is a separate reference to the same instance. If you change the retrieved reference to something else, the original reference inside the class will still point to the original instance.

In your example, I could retrieve a reference to sfFoo, and set that reference to null. However, the reference to sfFoo inside the Foo class is still intact.

In my opinion this makes the const keyword unnecessary.

I don't think you quite understand the purpose of const. It's not to guarantee that a particular area of memory will remain constant across a certain period of time. Rather, it forces a distinction between mutator and nonmutator methods, which turns out to be really useful for uncovering a variety of common logic errors.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
I don't think you quite understand the purpose of const. It's not to guarantee that a particular area of memory will remain constant across a certain period of time. Rather, it forces a distinction between mutator and nonmutator methods, which turns out to be really useful for uncovering a variety of common logic errors.


I'd say you're correct :)

Thanks

Share this post


Link to post
Share on other sites
Quote:
Original post by steven katic
pros and cons of good and bad programming aside you could make set private, thus:

class SomeFoo;
class Foo
{
private SomeFoo sfFOO = new SomeFoo();
public SomeFoo SomeFOO{ get{ return sfFOO ; } private set{ sfFOO = value; } }
}


this wouldn't help in this specific case...


Foo x = new Foo;
x.SomeFOO.Value = 13453;


The OP wants to prevent such manipulation of the original object stored in the property. This, afaik, is not possible. I've ran into this problem once till today, but I could work it around by a little redesigning.

Share this post


Link to post
Share on other sites
Quote:
Original post by davepermen
this wouldn't help in this specific case...


Foo x = new Foo;
x.SomeFOO.Value = 13453;


The OP wants to prevent such manipulation of the original object stored in the property. This, afaik, is not possible. I've ran into this problem once till today, but I could work it around by a little redesigning.


class SomeFoo
{
public readonly Value;
}
class Foo
{
private SomeFoo sfFOO = new SomeFoo();
public SomeFoo SomeFOO { get { return sfFOO; } } }
}

class test
{
Foo x = new Foo;
x.SomeFOO.Value = 13453; <- A readonly field cannot be assigned to.
}



[Edited by - Zanshibumi on May 24, 2007 6:28:52 AM]

Share this post


Link to post
Share on other sites
Wouldn't marking it read only only allow variable asignment to be in the constructor, so would would be readonly everywhere.

Share this post


Link to post
Share on other sites
Quote:
Original post by Niksan2
Wouldn't marking it read only only allow variable asignment to be in the constructor, so would would be readonly everywhere.

Yes.

I think I fail to see the problem. [Edit: I think I saw the problem now]


public class SomeFoo
{
internal int theValue;
public int Value { get { return theValue; } }
}

public class Foo
{
private SomeFoo sfFOO = new SomeFoo();
public SomeFoo SomeFOO { get { return sfFOO; } }

public void ChangeTheValue()
{
sfFOO.theValue = 33;
}
}
//The test class is in another assembly.
class test
{
public test()
{
Foo x = new Foo();
x.SomeFOO.Value = 13453; //error.
}
}



[Edited by - Zanshibumi on May 24, 2007 6:34:04 AM]

Share this post


Link to post
Share on other sites
but using the internal keyword doesn't that mean it has to sit in its own assembly ?

The only way I can think of doing it and is very ugly is to have 3 classes, and in turn creates problems depending the depth on teh class with the data.. like so




// exposed elsewhere
public class SomeFoo
{
protected int _value;
public int Value { get { return _value; } }
}

// local accessor
internal class SomeFooAccesor : SomeFoo
{
public SomeFoo SomeFOO { get { return this; } }
public void Assign(int val)
{
this._value = val;
}
};

public class Foo
{
private SomeFooAccesor _foo = new SomeFooAccesor();
public SomeFoo SomeFOO { get { return _foo; } }
public void DoSomething()
{
_foo.Assign(12);
}
};

Foo x = new Foo();
x.SomeFOO.Value = 1; // compile error








As said before, using structs is better and having the data duplicated should be temporary, and still has the member depth problem, so if you have in the structure a reference memebr you'll still have the problem there, and with const, what you're wanting is a compile time error/warning I guess :/

It is a problem.

Share this post


Link to post
Share on other sites
Quote:
Original post by Niksan2
but using the internal keyword doesn't that mean it has to sit in its own assembly?

No, It has to be in the same assembly as the class that is going to access it.


This would be easier with an example of a situation where this kind of separation is needed. :)

Share this post


Link to post
Share on other sites
Yeah that's what I meant, and agreed, depends on how it's going to be implimented to get a workaround for it.

Share this post


Link to post
Share on other sites
Well that sums up my question :(. Yea there are some good ideas here, but unfortunatly it just seems the best way to do this is to create a clone and send it back, or make it a value type. This is frustrating. Any1 have a link to some discussion topics on this? or some petition :)? or info if microsoft will be releasing a new version of C#?

For now I will waste some space and send a clone. The item im using does not want to be a struct unfortunatly(I need it to take as a reference in most cases).

Thanks VERY MUCH,
Brad

Share this post


Link to post
Share on other sites
Sorry if this has been suggested already, but...

have you considered writing an interface like


interface ISomeFooReadOnly
{
int Value { get; }
}


Then you could have the SomeFoo class implement it explicitly, like:

class SomeFoo : ISomeFooReadOnly
{
public int Value {get { return _value; } set {_value = value; } }

int ISomeFooReadOnly.Value { get { return Value; }}
}

then in your Foo class, have your SomeFOO property have the return type ISomeFooReadOnly. Then you just return it the way you are already doing it.

It's not as elegant a solution as const modifiers in C++, but it allows you to get around the problem by creating a read-only interface to a mutable object... you can't accidentally change what's in the object because you have to explicitly case it to the SomeFoo type to call any set accessors. Plus there's no copying involved.

[Edited by - kanato on May 25, 2007 12:07:24 PM]

Share this post


Link to post
Share on other sites
if i remember correctly in C# you can still pass a uncloned modifiable reference of a struct to a function, you just have to use the out keyword when passing it to keep it from cloning, i'm not sure if you can store the reference in non-function-parameter variable without cloning it though

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this