2
\$\begingroup\$

I came across the following code in our code base:

public interface ICloneable<T>
{
 T Clone();
}
public class MyObject : ICloneable<MyObject>
{
 public Stuff SomeStuff { get; set; }
 T Clone()
 {
 return new MyObject { SomeStuff = this.SomeStuff };
 }
}

The pattern of using a generic interface and then doing class A : Interface<A> looks pretty bizarre to me. I have a feeling it's either useless or that it could be changed into something less intricated. Can someone explain if this is right/wrong, and how it should be changed?

asked May 29, 2013 at 13:47
\$\endgroup\$
1
  • 3
    \$\begingroup\$ Implementation of the Clone should return MyObject not T. \$\endgroup\$ Commented May 29, 2013 at 14:39

2 Answers 2

1
\$\begingroup\$

You see this same pattern in the framework for IEquatable<T>. The most frequent use case for this is writing a generic method where you constrain the generic parameter type to implement the interface. This then allows you to write code in terms of a statically typed method Equals<T>. Another example is IComparable<T>, which is very handy for implementing methods relying on sorting without having to use the older style of providing an external Comparator class. For instance, the default comparison mechanism for the LINQ OrderBy method uses IComparable<T>, if it's available. In both of these cases, it's very natural to say that an instance of a type is comparable or equatable to other instances of the same type.

answered May 30, 2013 at 13:52
\$\endgroup\$
1
  • \$\begingroup\$ good point, it definitely makes sense it that case. Thanks \$\endgroup\$ Commented May 30, 2013 at 14:00
0
\$\begingroup\$

This pattern is called a Prototype object creation pattern. Usually it is used to do a deep cloning of objects (that is if Stuff is a reference type then it should also be cloned).

answered May 29, 2013 at 13:57
\$\endgroup\$
7
  • \$\begingroup\$ almaz, what I don't get is why make the interface generic \$\endgroup\$ Commented May 29, 2013 at 14:00
  • \$\begingroup\$ So that you get a typed instance. If you declare interface as non-generic, return value would be object. When you're cloning a MyObject instance it's logical to have a MyObject return value \$\endgroup\$ Commented May 29, 2013 at 14:08
  • \$\begingroup\$ almaz: yes I understand the intent, but isnt'it disturbing to have class A : I<A>. \$\endgroup\$ Commented May 29, 2013 at 14:35
  • 1
    \$\begingroup\$ ok, but if MyObject was ICloneable, I could do that too \$\endgroup\$ Commented May 29, 2013 at 15:43
  • 1
    \$\begingroup\$ Generic interface gives you ability to use result either generally (as object) or as specific type (when you know it). Non-generic ICloneable interface will require you to cast result in case you know the type. \$\endgroup\$ Commented May 29, 2013 at 16:20

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.