Как происходит это общее наследование (внутренне)?

2

Как вы думаете, следующий код? Это хорошо? Если да, то почему? Если нет, то почему это не так? И как CLR видит этот код?

public abstract class EntityBase<TEntity> : IEquatable<TEntity>
{        
    public bool Equals(TEntity other)
    {
        // check equalitiy
    }

    // yes, below is object Equals and GetHashCode method implementation
}

public class Person : EntityBase<Person>
{
}

У меня немного странное чувство. Как проблема с курицей и яйцом. И вот код рамки .Net, который имеет такое же поведение.

public sealed class String : IComparable<string>, IEquatable<string> // I removed other interfaces

Любые мысли?

  • 0
    Аккуратно, я не знал, что ты можешь сделать это :)
  • 3
    Хотя определение выглядит круглым, это не так. Однако алгоритм обнаружения цикла компиляторов C # ошибочен и слаб . Неправильно, потому что неправильно определяет нециклы как циклы, и слабо, потому что не может обнаружить некоторые очень неприятные циклы. Если эта тема вас интересует, см. Мою статью здесь: blogs.msdn.com/ericlippert/archive/2008/05/07/…
Показать ещё 3 комментария
Теги:
generics
.net-2.0

4 ответа

0
Лучший ответ

Для других людей я скопировал ответ Эрика Липперта (который отвечает в комментарии).

Хотя определение появляется круговой, это не так. Однако, С# алгоритм обнаружения циклов компиляторов как неправильные, так и слабые. Неправильно, потому что неправильно определяет нециклы как циклов и слабых, потому что не удается обнаруживают некоторые очень неприятные циклы. Если эта тема вас интересует, см. мой статью об этом здесь: http://blogs.msdn.com/ericlippert/archive/2008/05/07/covariance-and-contravariance-part-twelve-to-infinity-but-not-beyond.aspx

2

В правильных обстоятельствах (например, реализация IComparable<T>) это именно то, что нужно сделать.

Но это можно определить только в каждом конкретном случае, глядя на детали того, почему он рассматривается.

С другой стороны, С++ позволяет "любопытно повторяющийся базовый шаблон":

template<typename T>
class SomeWrapper<T> : T { ... ]

где общий класс наследует свою общую оболочку. Это позволяет использовать некоторые расширенные сценарии переноса, но может быстро запутываться при использовании за пределами упаковки. К счастью (?) Этот шаблон не разрешен в .NET.

  • 0
    @ Ричард: Да. От случая к случаю. Но как вы думаете о моем случае? :)
  • 0
    @Soe: недостаточно деталей. Необходимо знать, что Entity<T> делает с T (что он не может делать с this.GetType() ).
Показать ещё 1 комментарий
1

На самом деле это не ответ, но я нашел, что это имеет смысл после того, как я написал этот странный код...

class Program
{
    static void Main(string[] args)
    {
        var wife = new Human(Gender.Female);
        var baby = wife.GiveBirth();
        Console.WriteLine(baby.Gender);

        Console.ReadKey();
    }
}

class CanGiveBirthTo<T> where T : new()
{
    public CanGiveBirthTo()
    {
    }

    public T GiveBirth()
    {
        return new T();
    }
}

class Human : CanGiveBirthTo<Human>
{
    public Gender Gender { get; private set; }

    public Human(Gender gender)
    {
        Gender = gender;
    }

    public Human()
    {
        Gender = RandomlyAssignAGender();
    }

    Gender RandomlyAssignAGender()
    {
        var rand = new Random();
        return (Gender) rand.Next(2);
    }
}

enum Gender
{
    Male = 0,
    Female = 1
}
0

Я не вижу проблемы с вашим кодом. Почему это будет проблемой?

О внутреннем представлении dotNet JIT компилирует класс для каждой родовой версии. Итак, следующее:

class Foo<T> { public T Property; }
Foo<Int> fooint;
Foo<String> foostring;

Скомпилирован в:

class FooInt { public Int Property; } 
class FooString { public String Property; }
FooInt fooint;
FooString foostring;
// This is kept for if it is needed later.
// For example for generic casting, a C#4 feature.
class Foo<T> { public T Property; }
  • 0
    Интересной частью является класс Person: EntityBase <Person>. Вот почему он сказал, что это похоже на проблему с курицей и яйцом.
  • 0
    Ах, это, наверное, я, я все время делаю абсурдные конструкции, поэтому я не вижу в этом особенности: P.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню