Jump to content
  • Advertisement
Sign in to follow this  
Soth

[.net] Immutable objects in c#

This topic is 3913 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

in c++ you can write something like this
#include <map>
using namespace std;

class c
{
public:
const map<int,int>& Get(){return val;}
private:
map<int,int> val;
};

int main()
{
c inst;

inst.Get()[0]=0;//compile-time error, operator[] is not const
};




as i get there is no simple translation of this to c# ?

Share this post


Link to post
Share on other sites
Advertisement
Obviously only works for one collection per object, but allows you to access the object as blah[idx];


public class MyClass {
private Dictionary<string, string> m_MyDict = new Dictionary<string, string>();
public string this[string idx] {
get {
return m_MyDict[idx];
}
set {
throw new InvalidOperationException("Immutable");
}
}
}

Share this post


Link to post
Share on other sites
I think a more accurate translation would be:


public class C
{
private SortedList<int,int> val = new SortedList<int,int>();

public int this[int key]
{
get { return val[key]; }
}

C() {}
}





1. Leaving out the set accessor never even allows you to try to change a value,
Compile time errors are always better than runtime errors.
2. A SortedList captures the same behaviour as std::map ( ordered map of keys to values ), Dictionary is a Hash Table ( which would be std::unordered_map in C++ TR1 )

Share this post


Link to post
Share on other sites
Yes, I am aware that leaving out set causes a compile time error, I left it in as a demonstration. And SortedDictionary would accomplish the same thing, if you wanted to emulate std::map exactly...I rarely have the need to, so std::map -> Dictionary is usually fine for most people.

SortedList uses a little less memory, but SortedDictionary has O(log n) inserts and removes, rather than O(n), so I guess it depends on your usage.

Share this post


Link to post
Share on other sites
Well i think that my example was not completely to the point,
consider the following(c#):



class Symbol
{
//Symbol(Type type, Array array, )
private Type type;
public Symbol(Type ty)
{
type = ty;
}
public Type SymType
{
get
{
return type;
}
}


}

class Type
{
private int val;
private string name;

public int Val
{
get{return val;}
}

public string Name
{
get{return name;}
}
}






now in the client program i can write
Symbol sym=new Symbol(sometype);
Type t=Symbol.SymType;
t.val=88;//type in sym is modified

but the point is that i want user only to see what type is, not modify it.

Share this post


Link to post
Share on other sites
That doesn't work in your example.
Since you made val in Type private and only provided a get accessor, one can't change it.

So

Type t = symbol.SymType
t.Val = xx

will not compile.

But it comes down to one thing, in C++ you specify immutabilty at each point where a class is used, in C# you can only specify it in the definition of a class.

Share this post


Link to post
Share on other sites
Declare the internal data as 'readonly'. This allows you to set it at runtime through the constructor, but makes it immutable from then onwards.

Share this post


Link to post
Share on other sites
Quote:
Original post by BlodBath
Declare the internal data as 'readonly'. This allows you to set it at runtime through the constructor, but makes it immutable from then onwards.


Yah, but then it becomes immutable privately and publicly, which may not be what he wants.

Share this post


Link to post
Share on other sites
Quote:
Original post by GnomeTank
Quote:
Original post by BlodBath
Declare the internal data as 'readonly'. This allows you to set it at runtime through the constructor, but makes it immutable from then onwards.


Yah, but then it becomes immutable privately and publicly, which may not be what he wants.


It seems to satisfy the requirements of the posted examples; if he requires modification and cannot construct a new class to change the value of the readonly field, then I would say C# doesn't provide for that pattern.

Share this post


Link to post
Share on other sites
Well, it seems that I finally came with a most descriptive example of what i want to achieve ))



class Zip
{
public readonly List<int> lst;

public Zip()
{
lst=new List<int>();
}

}

static void Main(string[] args)
{

Zip z = new Zip();

z.lst.Add(99);//i dont want this to compile
}




in cpp if i return 'const list<int>&' i wont be able to modify it, but i guess that it is impossible to achieve in c# without some hacks. Thanks for your replies although.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!