Console.WriteLine
выводит string
на консоль.Но аргумент может быть любым объектом, а не просто строкой.Поэтому, если аргумент имеет какой-то другой тип (например, байтовый массив), он вызывает метод ToString()
объекта и записывает его.Это всегда работает, потому что все наследуется от object
и, следовательно, у каждого объекта есть метод ToString()
.
Но чаще всего этот ToString()
метод не переопределяется.Так что он просто выполняет object.ToString()
, который возвращает имя типа объекта.
Вот почему, если вы сделаете это:
var byteArray = new byte[] { };
Console.WriteLine(byteArray);
Вы получите это:
System.Byte []
Возможно, вы хотите увидеть отдельные значения, но ToString()
этого не возвращает.Он просто возвращает имя типа.Поэтому, если вы хотите на самом деле вывести значения для каждого байта, вам придется сделать это явно:
foreach(var b in byteArray)
Console.WriteLine(b);
Теперь вы не вызываете WriteLine(object)
.Вы звоните WriteLine(int)
(потому что byte
может быть неявно преобразовано в int
).int
может быть представлен как string
, поэтому теперь он знает, как записать значение в консоль.
Просто для развлечения и для иллюстрации концепции вы можете написать класскак это:
public class MyBytes : List<byte>
{
public override string ToString()
{
return "These are my bytes:"
+ Environment.NewLine
+ string.Join(Environment.NewLine, this);
}
}
Он наследуется от List<Byte>
и переопределяет ToString()
.Если вы создадите экземпляр MyBytes
, заполните его и запишите в консоль:
var byteArray = new byte[] { 1, 2, 3 };
var myBytes = new MyBytes();
myBytes.AddRange(byteArray);
Console.WriteLine(myBytes);
Вы увидите, что он вызывает ваш переопределенный метод ToString()
:
Это мои байты:
1
2
3
Это только для иллюстрации.Иногда, если мы знаем, что нам нужно вывести строковое представление класса, имеет смысл переопределить ToString()
, но я бы не стал создавать целый класс только для переопределения ToString()
.