Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/18: Рейтинг темы: голосов - 18, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 08.11.2015
Сообщений: 12

Чем заменить метод ToString() в структуре?

01.06.2016, 21:09. Показов 3811. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть у меня программа которую нужно немного переделать, а именно строку "public override string ToString()". Нужно убрать override из программы, но я не знаю, чем строку заменить чтобы выводился адекватный результат
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
 
namespace Students
{
public struct Student
{
private string firstName;
private string secondName;
private string thirdName;
private string adress;
private string telephone;
 
public string Familiya
{
get { return secondName; }
}
public String Telephone
{
get { return telephone; }
}
public void Add()
{
Console.Write("Введите Фамилию: ");
firstName = Console.ReadLine();
Console.Write("Введите Имя: ");
secondName = Console.ReadLine();
Console.Write("Введите Отчество: ");
thirdName = Console.ReadLine();
Console.Write("Введите Адрес: ");
adress = Console.ReadLine();
Console.Write("Введите Телефон?, а если его нет - поставьте  '0' ");
telephone = Console.ReadLine();
}
public override string ToString()
{
return String.Format("Имя-{0}\nФамилия-{1}\nОтчество-{2}\nАдрес-{3}\nТелефон-{4}\n\n", firstName, secondName,
thirdName, adress, telephone);
}
}
class Program
{
static void Main(string[] args)
{
int count;
do
{
Console.Clear();
Console.Write("Введите количество студентов:");
}
while (!int.TryParse(Console.ReadLine(), out count) || count < 1);
var students = new Student[count];
 
 
for (int i = 0; i < count; i++)
{
int k;
do
{
Console.Clear();
Console.WriteLine("1-Ввести данные для {0} студента", i + 1);
}
while (!int.TryParse(Console.ReadLine(), out k));
 
switch (k)
{
case 1: students[i].Add(); break;
}
Console.Clear();
}
Console.WriteLine(new string('-', 30));
Console.WriteLine("Сохраненные данные");
Console.WriteLine(new string('-', 30));
 
for (int i = 0; i < count; i++)
{
Console.Write(students[i]);
}
foreach (var student in students)
{
if (student.Telephone.Equals("0") || String.IsNullOrEmpty(student.Telephone))
{
Console.WriteLine("У студента с фамилией {0} нет номера", student.Familiya);
Console.ReadKey();
}
}
}
}
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.06.2016, 21:09
Ответы с готовыми решениями:

Конструктор,метод вывода на экран Display, метод для преобразования в строку toString в Delphi
Здравствуйте программисты!!! Мне в университете задали написать класс, а в этом классе использовать конструктор, метод вывода на экран...

Чем заменить метод Any() в .NET 2.0?
Всем привет. Как или чем можно заменить метод any() в framework 2.0 ибо он доступен только с 3.5 Допустим такая строка ...

Чем заменить метод Operators.CompareString?
Всем привет, хочу узнать чем можно заменить из Framework 4.5 на Framework 2.0 Кусок кода: if...

10
186 / 184 / 97
Регистрация: 30.04.2016
Сообщений: 478
01.06.2016, 21:23
Цитата Сообщение от СтепанАвреладзе Посмотреть сообщение
Нужно убрать override из программы
Интересно, зачем?

Цитата Сообщение от СтепанАвреладзе Посмотреть сообщение
чем строку заменить чтобы выводился адекватный результат
Убираете оверрайд, переименовываете ToString в GetIDisplayText (или во что либо другое) и строки 74-77 меняете на следующую
C#
1
Console.WriteLine(string.Join(Environment.NewLine, students.Select(s=>s.GetDisplayText())));
2
Эксперт .NET
 Аватар для Usaga
14138 / 9367 / 1350
Регистрация: 21.01.2016
Сообщений: 35,234
02.06.2016, 07:56
Лучший ответ Сообщение было отмечено СтепанАвреладзе как решение

Решение

Цитата Сообщение от golubyatnikovtv Посмотреть сообщение
Интересно, зачем?
Скорее всего, чтобы избежать оверхеда работы с таблицей виртуальных методов.

СтепанАвреладзе, избавиться от Override можно "сокрытием" виртуального метода базового класса:

C#
1
2
3
4
public new  string ToString()
{
   //blah-blah
}
Но вот эта строка всё-равно приведёт к упаковке:

C#
1
76 Console.Write(students[i]);
Замени её на:

C#
1
76 Console.Write(students[i].ToString());
Добавлено через 2 минуты
Если же твой вопрос был не об избавлении от упаковки, тогда повторю вопрос: зачем тебе это?
1
0 / 0 / 0
Регистрация: 08.11.2015
Сообщений: 12
02.06.2016, 08:22  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
зачем тебе это?
Цитата Сообщение от Usaga Посмотреть сообщение
Если же твой вопрос был не об избавлении от упаковки, тогда повторю вопрос: зачем тебе это?
Училку не устраивало наличие override в проге потому что мы видите ли не проходили еще эту тему
0
141 / 117 / 26
Регистрация: 07.12.2014
Сообщений: 371
02.06.2016, 08:54
Usaga, никакой таблицы виртуальных методов у значимых типов нет. И как раз таки переопределение ToString() уберёт необходимость упаковки объекта и соответствнно появления таблицы методов
0
186 / 184 / 97
Регистрация: 30.04.2016
Сообщений: 478
02.06.2016, 09:23
Цитата Сообщение от СтепанАвреладзе Посмотреть сообщение
Училку не устраивало наличие override в проге потому что мы видите ли не проходили еще эту тему

Не по теме:

Да она подавляет ваш потенциал! Бегите от неё!:)

0
Эксперт .NET
 Аватар для Usaga
14138 / 9367 / 1350
Регистрация: 21.01.2016
Сообщений: 35,234
02.06.2016, 09:26
Vigelforts, значимые типы наследуются от System.Object через System.ValueType. При обращении к любому из методов базового класса будет читаться таблица виртуальных методов (что не есть упаковка, но тоже мало приятного). Явная упаковку будет при попытке трактовать значимый тип как Object (у автора поста это происходит тут - 76 Console.Write(students[i]);).

Сокрытие виртуального метода позволяет избежать чтения таблицы виртуальных методов.

Пример:
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
 
namespace TestApplication
{
    public struct Student
    {
        public string Name { get; set; }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Student stud = new Student();
            stud.Name = "Us";
 
            string str = stud.ToString();
 
            Console.Write(stud);
            Console.ReadKey();
        }
    }
}

IL-код:

Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       52 (0x34)
  .maxstack  2
  .locals init ([0] valuetype TestApplication.Student stud)
  IL_0000:  ldloca.s   stud
  IL_0002:  initobj    TestApplication.Student
  IL_0008:  ldloca.s   stud
  IL_000a:  ldstr      "Us"
  IL_000f:  call       instance void TestApplication.Student::set_Name(string)
  IL_0014:  ldloca.s   stud
  IL_0016:  constrained. TestApplication.Student
  IL_001c:  callvirt   instance string [mscorlib]System.Object::ToString() <-- Обращение к таблице виртульных методов
  IL_0021:  pop
  IL_0022:  ldloc.0
  IL_0023:  box        TestApplication.Student <-- упаковка
  IL_0028:  call       void [mscorlib]System.Console::Write(object)
  IL_002d:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_0032:  pop
  IL_0033:  ret
} // end of method Program::Main


"Скрываем" базовый метод ToString():

Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
 
namespace TestApplication
{
    public struct Student
    {
        public string Name { get; set; }
 
        public new string ToString()
        {
            return Name;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Student stud = new Student();
            stud.Name = "Us";
 
            string str = stud.ToString();
 
            Console.Write(stud.ToString());
            Console.ReadKey();
        }
    }
}


Получаем:

Кликните здесь для просмотра всего текста

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       47 (0x2f)
  .maxstack  2
  .locals init ([0] valuetype TestApplication.Student stud)
  IL_0000:  ldloca.s   stud
  IL_0002:  initobj    TestApplication.Student
  IL_0008:  ldloca.s   stud
  IL_000a:  ldstr      "Us"
  IL_000f:  call       instance void TestApplication.Student::set_Name(string)
  IL_0014:  ldloca.s   stud
  IL_0016:  call       instance string TestApplication.Student::ToString() <-- нэма обращения к таблице
  IL_001b:  pop
  IL_001c:  ldloca.s   stud
  IL_001e:  call       instance string TestApplication.Student::ToString() <-- и от упаковки избавились
  IL_0023:  call       void [mscorlib]System.Console::Write(string)
  IL_0028:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_002d:  pop
  IL_002e:  ret
} // end of method Program::Main
0
141 / 117 / 26
Регистрация: 07.12.2014
Сообщений: 371
02.06.2016, 09:32
Usaga, правильно. Вы не переопределили через override ToString() поэтому он берётся из System.ValueType который по определению является ссылочным типом, что, естественно, потребует упаковки. Переопределение через override приведёт к вызову ToString() без необходимости таблицы виртуальных методов. А то, что Вы показываете, какой-то очень нехороший и ненужный костыль

. При обращении к любому из методов базового класса будет читаться таблица виртуальных методов (что не есть упаковка, но тоже мало приятного)
Это приводит к той самой упаковке в случае значимых типов
0
Эксперт .NET
 Аватар для Usaga
14138 / 9367 / 1350
Регистрация: 21.01.2016
Сообщений: 35,234
02.06.2016, 09:39
Vigelforts

Переопределяем ToString():

Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
 
namespace TestApplication
{
    public struct Student
    {
        public string Name { get; set; }
 
        public override string ToString()
        {
            return Name;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Student stud = new Student();
            stud.Name = "Us";
 
            string str = stud.ToString();
 
            Console.Write(stud.ToString());
            Console.ReadKey();
        }
    }
}


Получаем обращение к всё той-же таблице методов:

Кликните здесь для просмотра всего текста

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       59 (0x3b)
  .maxstack  2
  .locals init ([0] valuetype TestApplication.Student stud)
  IL_0000:  ldloca.s   stud
  IL_0002:  initobj    TestApplication.Student
  IL_0008:  ldloca.s   stud
  IL_000a:  ldstr      "Us"
  IL_000f:  call       instance void TestApplication.Student::set_Name(string)
  IL_0014:  ldloca.s   stud
  IL_0016:  constrained. TestApplication.Student
  IL_001c:  callvirt   instance string [mscorlib]System.Object::ToString() <-- !!!
  IL_0021:  pop
  IL_0022:  ldloca.s   stud
  IL_0024:  constrained. TestApplication.Student
  IL_002a:  callvirt   instance string [mscorlib]System.Object::ToString() <-- !!!
  IL_002f:  call       void [mscorlib]System.Console::Write(string)
  IL_0034:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_0039:  pop
  IL_003a:  ret
} // end of method Program::Main


Цитата Сообщение от Vigelforts Посмотреть сообщение
А то, что Вы показываете, какой-то очень нехороший и ненужный костыль
В каком месте костыль?

Добавлено через 2 минуты
Цитата Сообщение от Vigelforts Посмотреть сообщение
поэтому он берётся из System.ValueType
В ассемблерном листинге чётко видно, что обращение идёт к System::Object.
0
141 / 117 / 26
Регистрация: 07.12.2014
Сообщений: 371
02.06.2016, 09:57
Usaga, на уровне IL да, он действительно вызывает System.Object.ToString(); Но, JIT достаточно умён, чтобы при переопределении в значимом типе вычислить адрес метода по короткому пути. Вот пример ассемблера
1. Вызываем у значимого типа не передопределённый ToString()
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
            var personStringed = p.ToString();
021634EE  mov         ecx,4FD0F78h  
021634F3  call        00B630F4  
021634F8  mov         dword ptr [ebp-48h],eax  
021634FB  lea         eax,[ebp-40h]  
021634FE  mov         eax,dword ptr [eax]  
02163500  mov         edx,dword ptr [ebp-48h]  
02163503  lea         edx,[edx+4]  
02163506  call        739D1A18  
0216350B  mov         ecx,dword ptr [ebp-48h]  
0216350E  mov         eax,dword ptr [ecx]  
02163510  mov         eax,dword ptr [eax+28h]  
02163513  call        dword ptr [eax]  
02163515  mov         dword ptr [ebp-4Ch],eax  
02163518  mov         eax,dword ptr [ebp-4Ch]  
0216351B  mov         dword ptr [ebp-44h],eax
2.Вызываем переопределённый черещ override

Assembler
1
2
3
4
5
6
            var personStringed = p.ToString();
027434EE  lea         ecx,[ebp-40h]  
027434F1  call        02740D10  
027434F6  mov         dword ptr [ebp-48h],eax  
027434F9  mov         eax,dword ptr [ebp-48h]  
027434FC  mov         dword ptr [ebp-44h],eax
3. Вызываем перекрытый метод ToString():

Assembler
1
2
3
4
5
6
            var personStringed = p.ToString();
00B134EE  lea         ecx,[ebp-40h]  
00B134F1  call        00B10D08  
00B134F6  mov         dword ptr [ebp-48h],eax  
00B134F9  mov         eax,dword ptr [ebp-48h]  
00B134FC  mov         dword ptr [ebp-44h],eax
Ну и доп пример если override у ссылочного типа. Видимо отсутствие упаковки, что естественно, но работу с таблицей методов
Assembler
1
2
3
4
5
6
7
8
            var personStringed = p.ToString();
016B3509  mov         ecx,dword ptr [ebp-40h]  
016B350C  mov         eax,dword ptr [ecx]  
016B350E  mov         eax,dword ptr [eax+28h]  
016B3511  call        dword ptr [eax]  
016B3513  mov         dword ptr [ebp-4Ch],eax  
016B3516  mov         eax,dword ptr [ebp-4Ch]  
016B3519  mov         dword ptr [ebp-44h],eax
Так что никаких упаковок и таблиц методов. JIT оптимизирует

В каком месте костыль?
В том, что перекрытые методы это вообще беда, а уж тем более безпричинно )
0
Эксперт .NET
 Аватар для Usaga
14138 / 9367 / 1350
Регистрация: 21.01.2016
Сообщений: 35,234
02.06.2016, 10:22
Цитата Сообщение от Vigelforts Посмотреть сообщение
В том, что перекрытые методы это вообще беда, а уж тем более безпричинно )
Вот с этим я категорически согласен. Не зря я автора переспросил зачем ему это.

Цитата Сообщение от Vigelforts Посмотреть сообщение
Так что никаких упаковок и таблиц методов. JIT оптимизирует
Что ж, убедил. Спасибо.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.06.2016, 10:22
Помогаю со студенческими работами здесь

метод ToString
Здравствуйте. Пытаюсь преобразовать в string, выдает ошибку. Помогите. DWORD timer; timer=GetTickCount(); label1-&gt;Text =...

Point.ToString в чем ошибка?
Point point1; point1 = pictureBox1-&gt;Location; textBox1-&gt;Text = point1.ToString; задача такова, в text box записать координаты...

В чем разница parseInt - valueOf - toString ?
Собственно такой вопрос.

Как переопределить метод toString
public Flat getBestSpace() { double bestSpace = 0; Flat flatBestSpace = null; for (int i = 0; i &lt;...

Как вызывается метод toString
Здравствуйте. Подскажите пожалуйста откуда вызывается метод toString который формирует результирующую строку вывода. Во время создания...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru