一个类如何从其自身的参数化版本继承?

时间:2016-06-07 18:42:55

标签: c# .net oop

我看到了一个定义为

的C#类SomeClass
public class SomeClass : IComparable<SomeClass>, IEquatable<SomeClass>
{
   // ... 
}

我想知道如何将其翻译成英文。我理解它的方式似乎在逻辑上是不可能的。一个类如何从其自身的参数化版本继承?另外,这是一种常见的设计模式吗?

5 个答案:

答案 0 :(得分:7)

关键是要认识到它不是继承(或实现)本身的参数化版本,而是继承(或实现)另一个类或接口,并将其自身用作该目标类型的通用参数。

例如,IComparable<T>表示会有CompareTo()方法将T类型的对象作为参数。因此,通过实施IComparable<SomeClass>,您只需保证此类中存在具有该签名的方法:

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

是的,这是相当普遍的做法。类通常实现通用IComparable<>IEquatable<>接口,以显示它们可以与相同类型的其他项进行比较。也许值得一提的是,Java中的枚举被声明为扩展自己的Enum<> - 这种模式在C#中不是 common ,但确实会不时出现。

答案 1 :(得分:1)

翻译成&#34;英语&#34;它意味着:&#34;男孩(或女孩),在实现这些接口时,你最好是类型安全的,尤其是IComparable。否则,你必须进行类型转换,我想你不想要&#34;

请参阅下面的代码。 SomeClass实现了IComparable和IComparable。 查看CompareTo(object)和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();
        }
    }
}

答案 2 :(得分:0)

它不是继承,它正在实施IComparable Interface。发生了什么

Someclass实现IcomparableIEquatable接口。实现一个接口就像签署一份合同,说明你们这个类将在接口上实现这些方法。

Icomparable msdnIEquatable。如果您查看MSDN页面,您可以看到SomeClass gaurentees它将以某种方式实现这些方法。

这是非常常见的做法,它有许多不同的名称。我最常听到的是programming by contractImplementation over Inhertience。它可以让你做很多很酷的事情,比如依赖注入,正确的单元测试,更好的泛型。它这样做是因为编译器不需要知道对象正在实现的具体类。它只需要知道它具有某些功能。为了进一步阅读本文,我将阅读四个设计模式书的第一章。

Wikipedia link特别是第一章的介绍

答案 3 :(得分:0)

您发布的代码不会从任何类继承。它正在实现某些所谓的接口。如何翻译该片段:&#34;我保证SomeClass将是可比较的并且与其他SomeClass实例相同。我将在本课程中提供有关如何做到这一点的定义。&#34;

关于从其他类中专门化一个类...... 你能做的就是这样:

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Pet
    {
        protected string name;
        public Pet(String name)
        {
            this.name = name;
        }

    }

    class Dog : Pet
    {
        private List<String> tricks;
        public Dog(String name, List<String> tricks):base(name)
        {
            this.tricks = tricks;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<string> tricks = new List<string>();
            tricks.Add("sit");
            tricks.Add("jump");
            tricks.Add("bark");
            Dog puppy = new Dog("Fido", tricks);
        }
    }
}

狗继承自宠物。 Dog在创作时称Pet为构造函数。无论你传递给Dog构造函数的名称是什么,它都会将它转发给Pet构造函数。 因为会发生的事情是子类首先使用适当的参数调用其超类的构造函数。然后它运行自己的构造函数。无论在类中声明为public还是protected,它的子类都可以看到。

因此,狗会有名字和技巧列表:

puppy object result

你可以通过&#34; Locals&#34;来实现这种观点。窗口。

我建议您阅读有关c#inheritanceinterfacesgenerics

的一些教程

答案 4 :(得分:0)

用英语表达它是非常方便的,因为它是有效的代码,虽然我可能会把它看作是&#34; SomeClass是可比较的并且与它自己相等&#34; 。但这并没有真正解释发生了什么,它只是表达它的一种方式。

在C#类型中,泛型可以是其他类型的类别。通用类型基本上是&#34;类型构造函数&#34;。它们将其他类型作为参数,并使用它们来构造新类型。例如,IEnumerable<int>IEnumerable<string>两种完全不同的类型。非通用版本(IEnumerable)是第三个版本。在C#中,类型A可以继承任何其他类型B,只要以下都不是真的(我希望我没有错过任何内容):

  • B已经是A
  • 的子类型
  • B是一个类,A已经继承了另一个类
  • B是结构
  • A是界面,但B不是
  • A与B
  • 的类型相同
  • B密封
  • A是结构,B不是接口

这甚至使以下代码合法:

class Foo<T>
{
    public T Value;
}

class Foo : Foo<int>
{
}

FooFoo<T>是不同的类型,因此没有任何问题可以继承另一个。

您可以在此处阅读有关泛型的更多信息:

https://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx

关于这里的继承:

https://msdn.microsoft.com/en-us/library/ms173149.aspx