Конвертация бокса или конверсия идентичности? - PullRequest
0 голосов
/ 24 марта 2020

Я наткнулся на эту проблему, когда читал 3-е издание C# в глубине . Книга содержит следующее в Таблице 3.2 на стр.74.

class Sample<T> where T : IComparable<T> | Действительный : Sample<int> (преобразование в бокс), Недопустимый : Sample<FileInfo>

Давайте рассмотрим следующее.

using System;

public class Program
{
    public static void Main()
    {
        Sample<int> s1 = new Sample<int>();                 // ---(1.1)
        Sample<object> s2 = new Sample<object>();           // ---(1.2)
        Sample<OtherSample> s3 = new Sample<OtherSample>(); // ---(1.3)
        s1.Print();
        s2.Print();
    }
}

public class Sample<T> where T : IComparable<T> {
    public void Print() {
        Console.WriteLine(this);
    }
}

public class OtherSample : IComparableExtended<OtherSample> {
    public int CompareTo(OtherSample obj) {
        return 0;
    }
}

public interface IComparableExtended<T> : IComparable<T> {}

Очевидно, что 1.2 явно ошибочен, поскольку не существует неявного преобразования ссылок из object в System.IComparable<object>. У меня действительно нет проблем с 1.1, кроме того, что в книге написано, что это Boxing Conversion . Теперь int на самом деле является псевдонимом для Int32 struct, которая наследуется через иерархию Object->ValueType->Int32. Это реализует интерфейс System.IComparable<T> как IComparable<Int32>, поэтому версия 1.1 верна. Как я понял, where T : IComparable<T> означает, что T должно быть чем-то, что реализует IComparable . Я полагал, что Int32 реализует этот интерфейс и, следовательно, удовлетворяет ограничению типа для Sample<T>. В этом смысле действительно ли это Бокс Конверсия, как предполагает книга? Или это преобразование идентичности?

1.3 делает это еще более запутанным и противоречивым тому, что в книге. Когда public class Sample<T> where T : IComparable<T> сигнатура изменяется на public class Sample<T> where T : IComparableExtended<T>, даже 1.1 становится ошибкой времени компиляции.

Так что мой вопрос: можно ли рассматривать 1.1 как конвертирование в бокс? Или же вся моя идея о боксе и преобразованиях типа generi c неверна?

1 Ответ

3 голосов
/ 24 марта 2020

Это конвертация бокса.

Быстрый просмотр документации откроет страницу Бокс и распаковка (C# Руководство по программированию) , которая начинается со следующего текста:

Бокс - это процесс преобразования типа значения в объект типа или в любой тип интерфейса, реализованный этим типом значения.

(выделение мое)

Так как Sample<T> определен с общим ограничением c для интерфейса, он будет блокировать любую структуру, которая реализует этот интерфейс при инициализации с ним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...