Copying an object instance instead of a reference [modified]
-
This may be a stupid question, which may be easily solved if I just study the C# programming guide thoroughly, yet I expect help from Codeproject members as I don't have enough time. I've a library with a class called RegistryBrowser, that simply encapsulates the Microsoft.Win32.Registry and Microsoft.Win32.RegistryKey classes to provide a simple stateful access mechanism to the windows registry. This is a code fraction from the class:
public class RegistryBrowser
{
RegistryKey currentKey, regRoot, tempKey;
bool writable;
string temp;public string FullPath { get { return currentKey.Name; } } public int SubKeyCount { get { return currentKey.SubKeyCount; } } public int ValueCount { get { return currentKey.ValueCount; } } public RegistryBrowser(RegistryKey root, bool writable) { regRoot = root; currentKey = regRoot; this.writable = writable; } public RegistryBrowser(RegistryKey root, string subKey, bool writable) { regRoot = root; currentKey = regRoot.OpenSubKey(subKey, true); this.writable = writable; } public bool BrowseTo(string subKey) { tempKey = currentKey; currentKey = currentKey.OpenSubKey(subKey); if (currentKey == null) { currentKey = tempKey; return false; } else if(tempKey != regRoot) tempKey.Close(); return true; } . . .
Now the problem is that both the constructors simply copy the object reference 'root'. What if the calling method calls the .Close method on the same instance. I need to secure my library against this. So how do I copy the object, instead of just copying the reference, or maybe I need a better design. If so, please suggest. I encounter this problem very often and it's the source of most of bugs in my programs. Please suggest at the earliest.
modified on Friday, November 7, 2008 10:08 AM
-
This may be a stupid question, which may be easily solved if I just study the C# programming guide thoroughly, yet I expect help from Codeproject members as I don't have enough time. I've a library with a class called RegistryBrowser, that simply encapsulates the Microsoft.Win32.Registry and Microsoft.Win32.RegistryKey classes to provide a simple stateful access mechanism to the windows registry. This is a code fraction from the class:
public class RegistryBrowser
{
RegistryKey currentKey, regRoot, tempKey;
bool writable;
string temp;public string FullPath { get { return currentKey.Name; } } public int SubKeyCount { get { return currentKey.SubKeyCount; } } public int ValueCount { get { return currentKey.ValueCount; } } public RegistryBrowser(RegistryKey root, bool writable) { regRoot = root; currentKey = regRoot; this.writable = writable; } public RegistryBrowser(RegistryKey root, string subKey, bool writable) { regRoot = root; currentKey = regRoot.OpenSubKey(subKey, true); this.writable = writable; } public bool BrowseTo(string subKey) { tempKey = currentKey; currentKey = currentKey.OpenSubKey(subKey); if (currentKey == null) { currentKey = tempKey; return false; } else if(tempKey != regRoot) tempKey.Close(); return true; } . . .
Now the problem is that both the constructors simply copy the object reference 'root'. What if the calling method calls the .Close method on the same instance. I need to secure my library against this. So how do I copy the object, instead of just copying the reference, or maybe I need a better design. If so, please suggest. I encounter this problem very often and it's the source of most of bugs in my programs. Please suggest at the earliest.
modified on Friday, November 7, 2008 10:08 AM
Write a copy constructor[^] or implement ICloneable[^] interface.
*jaans
-
This may be a stupid question, which may be easily solved if I just study the C# programming guide thoroughly, yet I expect help from Codeproject members as I don't have enough time. I've a library with a class called RegistryBrowser, that simply encapsulates the Microsoft.Win32.Registry and Microsoft.Win32.RegistryKey classes to provide a simple stateful access mechanism to the windows registry. This is a code fraction from the class:
public class RegistryBrowser
{
RegistryKey currentKey, regRoot, tempKey;
bool writable;
string temp;public string FullPath { get { return currentKey.Name; } } public int SubKeyCount { get { return currentKey.SubKeyCount; } } public int ValueCount { get { return currentKey.ValueCount; } } public RegistryBrowser(RegistryKey root, bool writable) { regRoot = root; currentKey = regRoot; this.writable = writable; } public RegistryBrowser(RegistryKey root, string subKey, bool writable) { regRoot = root; currentKey = regRoot.OpenSubKey(subKey, true); this.writable = writable; } public bool BrowseTo(string subKey) { tempKey = currentKey; currentKey = currentKey.OpenSubKey(subKey); if (currentKey == null) { currentKey = tempKey; return false; } else if(tempKey != regRoot) tempKey.Close(); return true; } . . .
Now the problem is that both the constructors simply copy the object reference 'root'. What if the calling method calls the .Close method on the same instance. I need to secure my library against this. So how do I copy the object, instead of just copying the reference, or maybe I need a better design. If so, please suggest. I encounter this problem very often and it's the source of most of bugs in my programs. Please suggest at the earliest.
modified on Friday, November 7, 2008 10:08 AM
-
This may be a stupid question, which may be easily solved if I just study the C# programming guide thoroughly, yet I expect help from Codeproject members as I don't have enough time. I've a library with a class called RegistryBrowser, that simply encapsulates the Microsoft.Win32.Registry and Microsoft.Win32.RegistryKey classes to provide a simple stateful access mechanism to the windows registry. This is a code fraction from the class:
public class RegistryBrowser
{
RegistryKey currentKey, regRoot, tempKey;
bool writable;
string temp;public string FullPath { get { return currentKey.Name; } } public int SubKeyCount { get { return currentKey.SubKeyCount; } } public int ValueCount { get { return currentKey.ValueCount; } } public RegistryBrowser(RegistryKey root, bool writable) { regRoot = root; currentKey = regRoot; this.writable = writable; } public RegistryBrowser(RegistryKey root, string subKey, bool writable) { regRoot = root; currentKey = regRoot.OpenSubKey(subKey, true); this.writable = writable; } public bool BrowseTo(string subKey) { tempKey = currentKey; currentKey = currentKey.OpenSubKey(subKey); if (currentKey == null) { currentKey = tempKey; return false; } else if(tempKey != regRoot) tempKey.Close(); return true; } . . .
Now the problem is that both the constructors simply copy the object reference 'root'. What if the calling method calls the .Close method on the same instance. I need to secure my library against this. So how do I copy the object, instead of just copying the reference, or maybe I need a better design. If so, please suggest. I encounter this problem very often and it's the source of most of bugs in my programs. Please suggest at the earliest.
modified on Friday, November 7, 2008 10:08 AM
Ankit Rajpoot wrote:
Now the problem is that both the constructors simply copy the object reference 'root'. What if the calling method calls the .Close method on the same instance.
An object passed in is not copied. You only get a copy of the reference. Why don't you just create an internally used RegistryKey object, using the passed in object as a guide to the key to open??
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008 -
Ankit Rajpoot wrote:
I just study the C# programming guide thoroughly, yet I expect help from Codeproject members as I don't have enough time.
You can expect all you like, does not mean you'll get. And with an attitude like that im certainly not helping.
I said that just to glorify the helping nature of Codeproject members. I'm not a professional programmer working for some company. I'm a student who also need to study the academic course. I program just for the sake of my hobby. So what I mean by not having enough time is that I don't have time to study the guide and read the concepts. If someone can (please) tell me some straightforward way of doing that, I'd be very grateful. And if my attitude was bad, I'd not have said 'please'.
-
Write a copy constructor[^] or implement ICloneable[^] interface.
*jaans
ICloneable is generally not recommended[^]. It is ambiguous as to weather the call to clone will be a deep or shallow copy, so can introduce bugs if the caller makes the wrong assumptions. Recommendation is to define your own clone semantics and implement the required interfaces.
Simon
-
I said that just to glorify the helping nature of Codeproject members. I'm not a professional programmer working for some company. I'm a student who also need to study the academic course. I program just for the sake of my hobby. So what I mean by not having enough time is that I don't have time to study the guide and read the concepts. If someone can (please) tell me some straightforward way of doing that, I'd be very grateful. And if my attitude was bad, I'd not have said 'please'.
You just started your post rather badly. You basically said that the problem was easy to solve and that if you could be bothered you would do it your self, but you can't be bothered so you expect someone here to do the work for you. If you can't be bothered to put the effort it, why should you expect someone else to do it for you. I'm sure you didn't mean it like that, it was just worded badly.
Ankit Rajpoot wrote:
I'm not a professional programmer working for some company
Remember that people here aren't professionals paid to answer questions, we just do it because we are being generous. Don't expect an answer quickly every time. Looks like you've got some good answers to your question though. Personally, Dave's sounds like the best solution.
Simon
-
Ankit Rajpoot wrote:
Now the problem is that both the constructors simply copy the object reference 'root'. What if the calling method calls the .Close method on the same instance.
An object passed in is not copied. You only get a copy of the reference. Why don't you just create an internally used RegistryKey object, using the passed in object as a guide to the key to open??
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008Exactly my thought as well :) , like this...
static RegistryKey CopyKey(RegistryKey k, bool writeable) { string\[\] pathParts = k.Name.Split(new string\[\] { @"\\" }, StringSplitOptions.None); RegistryKey currentKey = null; // get the root key switch (pathParts\[0\].ToUpper()) { case "HKEY\_CLASSES\_ROOT": currentKey = Registry.ClassesRoot; break; case "HKEY\_CURRENT\_CONFIG": currentKey = Registry.CurrentConfig; break; case "HKEY\_CURRENT\_USER": currentKey = Registry.CurrentUser; break; case "HKEY\_DYN\_DATA": currentKey = Registry.DynData; break; case "HKEY\_LOCAL\_MACHINE": currentKey = Registry.LocalMachine; break; case "HKEY\_PERFORMANCE\_DATA": currentKey = Registry.PerformanceData; break; case "HKEY\_USERS": currentKey = Registry.Users; break; } if (pathParts.Length == 1) return currentKey; // walk the path of the original key to create a copy for (int pathPartIndex = 1; pathPartIndex < pathParts.Length; pathPartIndex++) { currentKey = currentKey.OpenSubKey(pathParts\[pathPartIndex\], writeable); } return currentKey; }
Keep It Simple Stupid! (KISS)
-
You just started your post rather badly. You basically said that the problem was easy to solve and that if you could be bothered you would do it your self, but you can't be bothered so you expect someone here to do the work for you. If you can't be bothered to put the effort it, why should you expect someone else to do it for you. I'm sure you didn't mean it like that, it was just worded badly.
Ankit Rajpoot wrote:
I'm not a professional programmer working for some company
Remember that people here aren't professionals paid to answer questions, we just do it because we are being generous. Don't expect an answer quickly every time. Looks like you've got some good answers to your question though. Personally, Dave's sounds like the best solution.
Simon
Thanks, And I agree, I started my post rather badly. That was, may be because I'm not a native English speaker & so I've difficulties fluently understanding the emotions that a statement conveys. Another reason is that I wanted my post to be extra polite and for the sake of it, I wrote that "it's a stupid question and can be solved by reading the guide", because I just thought that it's not worth bothering the geniuses for.
-
Exactly my thought as well :) , like this...
static RegistryKey CopyKey(RegistryKey k, bool writeable) { string\[\] pathParts = k.Name.Split(new string\[\] { @"\\" }, StringSplitOptions.None); RegistryKey currentKey = null; // get the root key switch (pathParts\[0\].ToUpper()) { case "HKEY\_CLASSES\_ROOT": currentKey = Registry.ClassesRoot; break; case "HKEY\_CURRENT\_CONFIG": currentKey = Registry.CurrentConfig; break; case "HKEY\_CURRENT\_USER": currentKey = Registry.CurrentUser; break; case "HKEY\_DYN\_DATA": currentKey = Registry.DynData; break; case "HKEY\_LOCAL\_MACHINE": currentKey = Registry.LocalMachine; break; case "HKEY\_PERFORMANCE\_DATA": currentKey = Registry.PerformanceData; break; case "HKEY\_USERS": currentKey = Registry.Users; break; } if (pathParts.Length == 1) return currentKey; // walk the path of the original key to create a copy for (int pathPartIndex = 1; pathPartIndex < pathParts.Length; pathPartIndex++) { currentKey = currentKey.OpenSubKey(pathParts\[pathPartIndex\], writeable); } return currentKey; }
Keep It Simple Stupid! (KISS)
Many thanks Ben :) :) :) I didn't expect anyone to post the complete method. Once again, many many many thanks, I'm really obliged.