Дженерики дают мне преимущества в производительности, плюсах и минусах? - PullRequest
4 голосов
/ 04 июня 2011

Я пытаюсь сгенерировать некоторые методы, как показано ниже, добавьте crm и human resources.Но я хочу написать Crm, humanResources, SupplChain и т. Д. (5-6 модулей), как писать простые коды ниже (ниже кодов - скелет :)) Сначала я написал без дженериков, а затем я написал с дженериками.Второе использование отличается от первого.1) Четкое чтение также управляемое и расходуемое
2) дает мне некоторые преимущества в производительности.Без процесса упаковки и распаковки

МОЖЕТЕ ЛУЧШЕ УЗНАТЬ МНЕ ЗА И ДУХ ОБОБЩЕНИЙ С СРАВНЕНИЕМ ПЕРВОГО И ВТОРОГО ИСПОЛЬЗОВАНИЯ?


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace App.GenericsBaseClass.Diff
{

    // View : 
    class Program
    {
        static void Main(string[] args)
        {
            new Crm().Add("Yapı Kredi");
            Console.Read();
            new HumanResources().Add("yusuf karatoprak");
            Console.Read();
        }
    }

  // Business
    public class Crm : Customer
    {
        public override void Add(object obj)
        {
            if (obj is String)
            {
                base.Add(obj);
            }
            else
            {
                throw new InvalidOperationException("Customer Name must be string Format...");
            }
        }
    }

    public class HumanResources : Staff
    {
        public override void Add(object obj)
        {
            if (obj is string)
            {
                base.Add(obj);
            }
            else
            {
                throw new InvalidOperationException("Stuff Name must be string Format...");
            }

        }
    }

    // Dal
    public class Staff
    {
        public virtual void Add(object obj)
        {
            new Db.Staff().Save((string)obj);
        }
    }

    public class Customer
    {
        public virtual void Add(object obj)
        {
            new Db.Customer().Save((string)obj);
        }

    }
    // Model
    public class Db
    {

        public class Customer
        {
            public void Save(string Name)
            {
                Console.WriteLine("Customer : {0} is saved",Name);
            }
        }

        public class Staff
        {
            public void Save(string Name)
            {
                Console.WriteLine("Staff: {0} is saved", Name);
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace App.GenericsInstadofBaseMethod
{
    class Program
    {
        static void Main(string[] args)
        {
            new Crm<string>().Add("Yapı Kredi");
            Console.Read();
            new HumanResources<string>().Add("yusuf karatoprak");
            Console.Read();
        }
    }

    // Business
    public class Crm<T> : Customer<T>
    {
        public override void Add(T obj)
        {
                base.Add(obj);
        }
    }

    public class HumanResources<T> : Staff<T>
    {
        public override void Add(T obj)
        {
                base.Add(obj);
        }
    }

    // Dal
    public class Staff<T>
    {
        public virtual void Add(T obj)
        {
            new Db<T>.Staff().Save(obj);
        }
    }

    public class Customer<T>
    {
        public virtual void Add(T obj)
        {
            new Db<T>.Customer().Save(obj);
        }

    }
    // Model

    public class Db<T> 
    {
        public class Customer
        {
            public void Save(T Name)
            {
                Console.WriteLine("Customer : {0} is saved", Name.ToString());
            }
        }

        public class Staff
        {
            public void Save(T Name)
            {
                Console.WriteLine("Staff: {0} is saved", Name);
            }
        }

    }
}

Ответы [ 5 ]

3 голосов
/ 04 июня 2011

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

Статья

Использование дисперсии в интерфейсах для общих коллекций

Часто задаваемые вопросы по ковариации и контрастности (обновление .NET 4.0)

Плюсы

С помощью дженериков вы получаете безопасность типов как во время выполнения, так и во время проектирования. Вы можете получать сведения о ваших объектах в режиме реального времени, как если бы они были жестко запрограммированы для определенного типа. Это очень полезно при настройке обоих методов расширения, и ... ну почти во всем остальном. На самом деле, начиная с .NET 2.0, я даже больше не использую неуниверсальные списки для чего-либо, кроме типа object

  • Редактировать

Как уже отмечали другие, это исключает необходимость распаковки.

Против

Из-за различий в природе противоречивости и ковариации, это может привести к путанице в отношении того, что является и не является приемлемым в родовом в разы. Например, если вы рассмотрите следующий макет ..

interface IBase {
}

class Alpha : IBase {
}

class Beta : Alpha {
}

IList<IBase> ListOfObjects { get; set; }

Это сбивает с толку. Можете ли вы передать в список объекты Alpha и Beta? Когда я попробовал, ты не смог. Но потом сработало следующее.

IList<Alpha> ListOfObjects { get; set; }

Он принимает как Alpha, так и Beta объекты, потому что Beta наследует Alpha

Посмотрите больше информации о контравариантности и ковариации здесь . Это очень полезно.

Я никогда не заметил снижения производительности от дженериков. Однако это не означает, что они не существуют. Тем не менее, они просто простые объекты, поэтому я не могу видеть, где будут накладные расходы. В общем, компилятор не должен даже позволять вам запускать код, в котором вы пытаетесь добавить неподходящие объекты в общий список, и если он это делает, то вы где-то допустили ошибку конструктора, или используете dynamics, или работаете с проблема контравариантности против ковариации. Хотя я понимаю, что кое-что изменилось с .NET 4.0.

2 голосов
/ 04 июня 2011

Помимо моего поста, объясняющего некоторые вещи о дженериках, ваша ситуация здесь не выглядит так, как будто она действительно требует их вообще.Вместо этого вам следует добавить свойство в ваш класс.

public class Person {
   public string Name { get; set; }
}
public class Customer : Person {

}
public class Staff : Person {
}

public class HumanResources : Staff {
}

public class Db {
  public List<Customer> Customers { get; set; }
  public List<Staff> Staff { get; set; }
}

public static void Main(){ 
  var db = new Db {
     Customers = new List<Customer> { },
     Staff = new List<Staff> { }
  };

  Db.Customers.Add(new Customer { Name = "Primary Customer" } );
  Db.Staff.Add(new Staff { Name = "Employee Prime" } );
  Db.Staff.Add(new HumanResources { Name = "Human Resource Manager" });
}

Обобщения должны использоваться, чтобы настаивать на вводимом типе, а не на самом деле контролировать данные.В приведенном вами примере дженерики не используются по-настоящему.

В этом примере вы создаете базовый класс, а затем три подтипа, один из которых наследуется от другого подтипа.Таким образом, у вас есть Customer и Staff в качестве двух основных типов, которые Db (если предположить, что это сокращение от базы данных) принимает.

Db может принимать список Customer с и список Staff, поскольку HumanResources является типом Staff, вы можете хранить их вместе.Вы также можете добавить List<Person> People { get; set; }, и он будет принимать все типы, поскольку они неизбежно наследуются друг от друга.

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

public class Person { 
   public Person(string name) { 
      this.Name = name; }
   }

   public string Name { get; private set; }
}

В этом примере мы настраиваем поле Name, чтобы его могли видеть все, но только изменено и установлено при создании (на самом деле не лучшая идея, но оно демонстрирует смысл).

Итак, теперь вы бы добавили новый Customer, как это ..

Db.Customers.Add( new Customer ( "Ciel" ) ); или новый посох ... Db.Staff.Add( new Staff( "Darin" ) );.

2 голосов
/ 04 июня 2011

Не думаю, что разница в производительности значительна.

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

1 голос
/ 04 июня 2011

Generics - это безопасность типов imho.Вы можете написать более надежный код, так как вы получаете ошибки времени компиляции вместо пробной версии и террора.

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

0 голосов
/ 11 января 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...