tag:blogger.com,1999:blog-8259613.post8226908569784344509..comments2023-08-05T11:16:50.347+02:00Comments on Kristof Verbiest - Bite-size C#: A type-safe pattern to implement ICloneable and similar interfacesKristofhttp://www.blogger.com/profile/01727380410232817527noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-8259613.post-50201527585021541432009-04-20T09:02:00.000+02:002009-04-20T09:02:00.000+02:00@Anonymous: when no precautions are taken, then yo...@Anonymous: when no precautions are taken, then you defenitely need to cast the result because it will be of type System.Object.<br /><br />The pattern that I described will make sure that no cast is needed, and it will behave in the way that you say...Kristofhttps://www.blogger.com/profile/01727380410232817527noreply@blogger.comtag:blogger.com,1999:blog-8259613.post-80195329181482298552009-04-19T22:51:00.000+02:002009-04-19T22:51:00.000+02:00Your test code is below
Test t = new Test();
...Your test code is below<br /><br /><br /> Test t = new Test();<br /><br /> Test t2 = t.Clone() as Test; // cast needed<br /><br />Why would a cast be needed? Your code compile fine with out a cast. The reason is that above test code fragment will not call method Object ICloneable.Clone ( ). Rather it calls pubic Test Clone( ). And if it calls that then why a cast is needed? I ran your code through a debugger to confirm that.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8259613.post-77507196984379821002009-03-27T19:43:00.000+01:002009-03-27T19:43:00.000+01:00Thanks. This helped point me in a good direction....Thanks. This helped point me in a good direction.<BR/><BR/>Here's a C++/CLI version:<BR/><BR/>http://msdn.microsoft.com/en-us/library/ms235235.aspxAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-8259613.post-67990648917564008762008-10-27T15:09:00.000+01:002008-10-27T15:09:00.000+01:00steven: you're absolutely right. I must admit ...steven: you're absolutely right. I must admit that I hadn't thought about this until now. Thanks for the comment!<BR/><BR/>I wanted to give an example that uses an interface that everybody knows. Of course you can use this pattern on other interfaces as well (you might want to make an IShallowCloneable interface for instance).<BR/><BR/>When implementing an interface such as IEnumerable<T>, the code that is generated by Visual Studio actually uses this pattern: it will implement a 'normal' GetEnumerator() skeleton that returns a type-safe IEnumerator<T>. But it also generates the skeleton for a GetEnumerator() method that returns an IEnumerator that is not type-safe. When you implement this second method, you typically just call the type-safe version (as in my example).Kristofhttps://www.blogger.com/profile/01727380410232817527noreply@blogger.comtag:blogger.com,1999:blog-8259613.post-15553194215347877362008-10-22T22:14:00.000+02:002008-10-22T22:14:00.000+02:00I think this is a good and easy pattern. However, ...I think this is a good and easy pattern. However, you chose the wrong example :-). <BR/><BR/>You shouldn't use the ICloneable interface, because the interface isn't very helpful. I've never ever seen anyone ever cast an object of a certain type to an ICloneable and call clone on it. The problem with ICloneable is that the interface doesn't specify how the object is cloned (deep or shallow). For this reason the interface is unusable and should have been depricated. It's because of this that the .NET Framework Design Guidelines state that you shouldn't use it.<BR/><BR/>Of course it’s completely fine to have a Clone() method on your type (like in your example) and return a strongly typed object, as long as your comments state whether it’s doing a deep or a shallow copy.Anonymousnoreply@blogger.com