Я пытаюсь ответить на практический вопрос из книги по дженерикам, но для меня этот вопрос не имеет смысла. Вот оно.
Создайте два класса с идентичной функциональностью. Используйте универсальные шаблоны для первого класса и приведите второй класс к типам объектов. Создайте цикл 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;
}
Не знаю, правильно ли я делаю. Помогите, пожалуйста :-)





Я думаю, что вопрос просит вас создать класс коллекции и вставить в него экземпляры вашего класса.
Например.,
Версия 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));
Я не проверял, компилируется ли это, и теперь мне нужно запустить.
На самом деле, поскольку Human является эталонным типом, бокса не происходит, поэтому тайминги будут почти идентичными.
Я думаю, вы все правильно поняли, за исключением циклов for. Int - это тип объекта, поэтому замените
object her = (object)per.Value;
с
int her = per.Value;
Еще вам не хватает счетчиков производительности. Взгляните на класс Timer, чтобы увидеть, что вы можете сделать, чтобы увидеть, какой из них лучше работает.
«Int - это тип объекта». Это должно быть «Int - это тип VALUE».
Я не уверен, но для меня это звучит как вопрос, пытающийся проверить ваше знание правил бокс и распаковка.
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 является эталонным типом, бокса не происходит, поэтому тайминги будут почти идентичными.
Что ж, если я делаю это правильно, то, согласно моим счетчикам (DateTime.Now.Ticks), я вообще не вижу никакой разницы в производительности.
Если я воспользуюсь подходом с порядком байтов, то я смогу увидеть, где падает производительность.
Будем надеяться, что мои экзаменационные вопросы будут немного яснее.
Спасибо всем.
Согласен, вопрос не очень ясен. Вы можете набрать его именно для нас?
Если вы используете dotnet framework 2.0 или выше, вы можете взглянуть на System.Diagnostics.Stopwatch, чтобы определить время. [msdn.microsoft.com/en-us/library/…
Что вас просят сделать, так это использовать 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();
Существует большая разница в производительности, поскольку дженерики работают примерно в два раза быстрее.
Здесь отсутствует зацикливание. В остальном это выглядит хорошо. Общая версия будет работать лучше. Вы можете проверить это с помощью класса StopWatch в System.Diagnostics.