Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a class inherit from a parameterized version of itself?

Tags:

c#

.net

oop

I saw a C# class SomeClass that was defined like

public class SomeClass : IComparable<SomeClass>, IEquatable<SomeClass>
{
   // ... 
}

and I'm wondering how to translate that into English. The way I understand it seems logically impossible. How can a class inherit from a parameterized version of itself? Also, is this a common design pattern?

like image 642
Ms. Corlib Avatar asked Jun 07 '16 18:06

Ms. Corlib


People also ask

Can a class inherit from itself?

The class doesn't inherit itself. Every instatiation of Model<N> is a different, unrelated class.

Can a class inherit from itself java?

No, a class cannot extend itself in java.

Can a class inherit itself python?

This means that Python supports inheritance, and as you'll see later, it's one of the few languages that supports multiple inheritance. When you write Python code using classes, you are using inheritance even if you don't know you're using it. Let's take a look at what that means.

Is it possible to inherit from a generic type?

You can't inherit from a Generic type argument. C# is strictly typed language. All types and inheritance hierarchy must be known at compile time. . Net generics are way different from C++ templates.


2 Answers

The key is to recognize that it's not inheriting from (or implementing) a parameterized version of itself, but rather inheriting from (or implementing) another class or interface, and using itself as a generic parameter for that target type.

For example, IComparable<T> says that there will be a CompareTo() method that takes an object of type T as a parameter. So by implementing IComparable<SomeClass> you're simply guaranteeing that a method with that signature will exist on this class:

public class SomeClass : IComparable<SomeClass>
{
    public int CompareTo(SomeClass other)
    {
        //...
    }
}

And yes, this is fairly common practice. Classes often implement the generic IComparable<> and IEquatable<> interfaces to show that they can be compared with other items of the same type. It's maybe also worth mentioning that enums in Java are declared as extending Enum<> of themselves--a pattern which is not common in C#, but does appear from time to time.

like image 158
StriplingWarrior Avatar answered Oct 08 '22 04:10

StriplingWarrior


Translated in "English" it means: "Boy (or girl), you'd better be type-safe when implementing those interfaces, especially IComparable. Otherwise, you'll have to perform type casting, which I guess you don't want"

See the code below. SomeClass implemented IComparable and IComparable. See differencies between implementations of CompareTo(object) and CompareTo(SomeClass).

namespace InterfacesStuff
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var someClass1 = new SomeClass {ComparedValue = 1};
            var someClass2 = new SomeClass {ComparedValue = 2};

            //someClassObject defined as SomeClass
            //object someClassObject = new SomeClass { ComparedValue = 2 };

            //someClassObject defined as anything else but SomeClass
            object someClassObject = 5;

            int comparisonSomeClassBySomeClass = someClass1.CompareTo(someClass2);

            int comparisonSomeClassByObject = someClass1.CompareTo(someClassObject);
        }
    }


    public class SomeClass : IComparable, IComparable<SomeClass>, IEquatable<string>, IEquatable<int>,
        IEquatable<double>
    {
        public int ComparedValue;

        public int CompareTo(object obj)
        {
            var presumedSomeClassObject = obj as SomeClass;

            if (presumedSomeClassObject != null)
            {
                if (ComparedValue <= ((SomeClass) obj).ComparedValue)
                    return -1;
            }

            return 0;
        }

        public int CompareTo(SomeClass other)
        {
            if (ComparedValue <= other.ComparedValue)
                return -1;

            return 0;
        }

        public bool Equals(double other)
        {
            throw new NotImplementedException();
        }

        public bool Equals(int other)
        {
            throw new NotImplementedException();
        }

        public bool Equals(string other)
        {
            throw new NotImplementedException();
        }
    }
}
like image 34
Bav Avatar answered Oct 08 '22 04:10

Bav