Вопрос о дженериках C#

Я пытаюсь ответить на практический вопрос из книги по дженерикам, но для меня этот вопрос не имеет смысла. Вот оно.

Создайте два класса с идентичной функциональностью. Используйте универсальные шаблоны для первого класса и приведите второй класс к типам объектов. Создайте цикл for, который использует класс и класс на основе объекта, чтобы определить, какой из них работает лучше.

Я не уверен, что это значит при приведении к типам объектов. Вот мой код на данный момент

   //Generic
    class Person<T> {

        T var1;

        public Person(T yer) {
            var1 = yer;
        }

        public T Value { get { return var1; } }
    }

    //Normal class
    class Human {

        int var1;

        public Human(int yer) {
            var1 = yer;
        }

        public int Value { get { return var1; } }
    }

Моя основная программа, запускающая циклы

for (int i = 0; i < 1000000; i++) {
                Person<int> me = new Person<int>(1);
                int hey = me.Value;
            }

            for (int i = 0; i < 1000000; i++) {
                Human per = new Human(1);
                object her = (object)per.Value;
            }

Не знаю, правильно ли я делаю. Помогите, пожалуйста :-)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 005
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

Я думаю, что вопрос просит вас создать класс коллекции и вставить в него экземпляры вашего класса.

Например.,

Версия Generics:

List<Human> myList = new List<Human>();
Human h = new Human();
myList.Add(h);

Версия объекта:

ArrayList myObjectList = new ArrayList();
Human h = new Human();
myObjectList.Add((object)h));

Я не проверял, компилируется ли это, и теперь мне нужно запустить.

Здесь отсутствует зацикливание. В остальном это выглядит хорошо. Общая версия будет работать лучше. Вы можете проверить это с помощью класса StopWatch в System.Diagnostics.

Pradeep 21.10.2008 15:10

На самом деле, поскольку Human является эталонным типом, бокса не происходит, поэтому тайминги будут почти идентичными.

James Curran 21.10.2008 15:32

Я думаю, вы все правильно поняли, за исключением циклов for. Int - это тип объекта, поэтому замените

object her = (object)per.Value;

с

int her = per.Value;

Еще вам не хватает счетчиков производительности. Взгляните на класс Timer, чтобы увидеть, что вы можете сделать, чтобы увидеть, какой из них лучше работает.

«Int - это тип объекта». Это должно быть «Int - это тип VALUE».

James Curran 21.10.2008 15:36

Я не уверен, но для меня это звучит как вопрос, пытающийся проверить ваше знание правил бокс и распаковка.

int i = 123; объект o = (объект) i; // заниматься боксом

Затем объект o можно распаковать и присвоить целочисленной переменной i:

о = 123; я = (int) o; // распаковка

Если объект упаковывается и распаковывается, это происходит медленнее по мере создания нового объекта.

Да, вы все делаете правильно. С чистыми экземплярами Object мало что можно сделать, так как большинство операторов с ними не работают. Определены четыре общедоступных метода: Equals, GetHashCode, GetType и ToString. Я думаю, вы могли бы поиграть с Equals и посмотреть, имеет ли это значение.

Я думаю, что вопрос в том, чтобы перебрать коллекцию ваших классов.

Общий

List<Person> pList = new List<Person>();
for(int i = 0; i<1000; ++i)
    pList.Add(new Person(30));

StopWatch sw = new StopWatch();
sw.start();
int sum = 0;
foreach(Person p in pList)
    sum += p.Value;
sw.Stop();

Объект

ArrayList hList = new ArrayList;
for(int i = 0; i<1000; ++i)
    hList.Add(new Human(30));

StopWatch sw = new StopWatch();
sw.start();
int sum = 0;
foreach(Object h in hList)
    sum += ((Human)h).Value;
sw.Stop();

На самом деле, поскольку Human является эталонным типом, бокса не происходит, поэтому тайминги будут почти идентичными.

James Curran 21.10.2008 15:34

Что ж, если я делаю это правильно, то, согласно моим счетчикам (DateTime.Now.Ticks), я вообще не вижу никакой разницы в производительности.

Если я воспользуюсь подходом с порядком байтов, то я смогу увидеть, где падает производительность.

Будем надеяться, что мои экзаменационные вопросы будут немного яснее.

Спасибо всем.

Согласен, вопрос не очень ясен. Вы можете набрать его именно для нас?

endian 21.10.2008 15:41

Если вы используете dotnet framework 2.0 или выше, вы можете взглянуть на System.Diagnostics.Stopwatch, чтобы определить время. [msdn.microsoft.com/en-us/library/…

Kinjal Dixit 21.10.2008 15:57

Что вас просят сделать, так это использовать Object внутри вашего класса, поэтому Person <> идеален. Что вам нужно сделать, так это изменить Human так, чтобы Var1 стал объектом. Затем, где бы вы ни использовали var1, приведите его к int или из int:

class Human 
{        
     object var1;
     public Human(int yer) 
     {            
          var1 = (object) yer;        
     }
     public int Value 
     { 
         get { return (int) var1;     }
     }    
}

Путаница возникает из-за того факта, что в этом примере var1 действительно не может быть ничем, кроме int, поэтому он действительно не является хорошим кандидатом для дженериков, и в производстве должен быть написан так, как вы изначально написали Human. Но, как я уже писал, для этого упражнения это нормально.

Я знаю, что это последнее добавление к этому вопросу, но я точно использовал этот код и заставил его работать, используя DateTime.Now.Ticks, просто обновив следующее:

        DateTime t = DateTime.Now;
        for (int i = 0; i < 1000000; i++)
        {
            Person<int> me = new Person<int>(1);
            int hey = me.Value;
        }
        long a = DateTime.Now.Ticks - t.Ticks;
        TimeSpan A = new TimeSpan(a);


        for (int i = 0; i < 1000000; i++)
        {
            Human per = new Human(1);
            object her = (object)per.Value;
        }

        long b = DateTime.Now.Ticks - t.Ticks;
        TimeSpan B = new TimeSpan(b);

        Console.WriteLine(A.ToString());
        Console.WriteLine(B.ToString());
        Console.ReadLine();

Существует большая разница в производительности, поскольку дженерики работают примерно в два раза быстрее.

Другие вопросы по теме