Hello. I decided to read Richter (after Shildt) and got into confusion. As far as I knew before, the interface and enum are not inherited from the object, but after such a code I am confused
IComparable F; F.ToString(); // или любой другой метод object, написал для демонстрации Console.WriteLine(typeof(IComparable).BaseType) //пустая строка
The confusion is that, first, where did the built-in object
methods come from the interface and enum
? And secondly, I have already come to terms with this, but the last line displays a blank screen instead of the name of the base class. How can this be understood, please tell me, if you consider that the interface is supposedly inherited from the object?
Then I met in his book "CLR VIA C # 4.5" page 167 (the penultimate block of the example code) the phrase in this code
using System; internal struct Point : IComparable { private Int32 m_x, m_y; // Конструктор, просто инициализирующий поля public Point(Int32 x, Int32 y) { m_x = x; m_y = y; } // Переопределяем метод ToString, унаследованный от System.ValueType public override String ToString() { // Возвращаем Point как строку (вызов ToString предотвращает упаковку) return String.Format("({0}, {1})", m_x.ToString(), m_y.ToString()); } // Безопасная в отношении типов реализация метода CompareTo public Int32 CompareTo(Point other) { // Используем теорему Пифагора для определения точки, // наиболее удаленной от начала координат (0, 0) return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y) - Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y)); } // Реализация метода CompareTo интерфейса IComparable public Int32 CompareTo(Object o) { if (GetType() != o.GetType()) throw new ArgumentException("o is not a Point"); // Вызов безопасного в отношении типов метода CompareTo return CompareTo((Point)o); } } public static class Program { public static void Main() { // Создаем в стеке два экземпляра Point Point p1 = new Point(10, 10); Point p2 = new Point(20, 20); // p1 НЕ пакуется для вызова ToString (виртуальный метод) Console.WriteLine(p1.ToString()); // "(10, 10)" // p1 ПАКУЕТСЯ для вызова GetType (невиртуальный метод) Console.WriteLine(p1.GetType()); // "Point" // p1 НЕ пакуется для вызова CompareTo // p2 НЕ пакуется, потому что вызван CompareTo(Point) Console.WriteLine(p1.CompareTo(p2)); // "-1" // p1 ПАКУЕТСЯ, а ссылка размещается в c IComparable c = p1; Console.WriteLine(c.GetType()); // "Point" // p1 НЕ пакуется для вызова CompareTo // Поскольку в CompareTo не передается переменная Point, // вызывается CompareTo(Object), которому нужна ссылка // на упакованный Point // c НЕ пакуется, потому что уже ссылается на упакованный Point Console.WriteLine(p1.CompareTo(c)); // "0" // c НЕ пакуется, потому что уже ссылается на упакованный Point // p2 ПАКУЕТСЯ, потому что вызывается CompareTo(Object) Console.WriteLine(c.CompareTo(p2));// "-1" // c пакуется, а поля копируются в p2 p2 = (Point)c; // Убеждаемся, что поля скопированы в p2 Console.WriteLine(p2.ToString());// "(10, 10)" } }
// c пакуется, а поля копируются в p2
but how can it be packaged if it refers to an already packed structure ?? After all, when an interface assigns a type to a value, then a package occurs (earlier, in the code, the interface was assigned a type of value)