Reputation: 2966
i'm trying to generate some methods like below, add crm
and human resources
. But i want to write Crm,humanResources,SupplChain etc. (5-6 Modules) how to write below codes simple(Below codes is skeleton :))
i'd written without generics first and then i've written with generics. Second usage differs from first.
1) Clear reading also managed and expendable
2) give me some performance advantages. No boxing and unboxing process
CAN YOU teach me pros and cons of generics WITH compare first and second usage?
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);
}
}
}
}
Upvotes: 4
Views: 2630
Reputation: 1
Here you can find a very interesting video on the Advantages and Disadvantages of using generics.
Upvotes: 0
Reputation: 101192
Generics is all about type safety imho. You get to write more robust code, since you get compile time errors instead of runtime trial&terror.
Boxing is a bonus, but you should not choose generics just to avoid boxing (which sounds like premature optimization).
Upvotes: 1
Reputation: 17782
Aside from my post explaining some things about generics, your situation here doesn't look like it really requires them at all. You should instead add a property to your class.
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" });
}
The generics should be used to insist on the type that goes in, not to actually control the data. The example you have isn't using generics in its real intended fashion.
In this example, you create a base class and then three sub-types, one of which inherits from another sub-type. So you have Customer
and Staff
as your two primary types that the Db
, (assuming that is short for database) accepts.
The Db
can take a List of Customer
s and a list of Staff
, since HumanResources
is a type of Staff
you can store them together. You could also add a List<Person> People { get; set; }
and it would accept all of the types since they inevitably inherit from each other.
As for enforcing strings, that would be better done in your constructors.
public class Person {
public Person(string name) {
this.Name = name; }
}
public string Name { get; private set; }
}
In this example, we are setting up the Name
field so that it can be seen by everything, but only changed and set at creation (not really the best idea, but it demonstrates the point).
So now, you would add a new Customer
like this ..
Db.Customers.Add( new Customer ( "Ciel" ) );
or a new Staff... Db.Staff.Add( new Staff( "Darin" ) );
.
Upvotes: 2
Reputation: 17782
From what little I understand, most operations with Generics happen at the IL
level, so there is not much of a performance hit, if any at all. All it does is force and check objects to be of a certain type. The biggest con is the understanding of contravariance and covariance. Here are some articles about it.
Using Variance in Interfaces for Generic Collections
Covariance and Contravariance FAQ (.NET 4.0 Updated)
With generics, you get type-safety both in your runtime, and your design time. You are able to receive intellisense about your objects in real time as if they were hard-coded for a specific type. This is very useful when setting up both extension methods, and ...well pretty much everything else. In fact, since .NET 2.0, I do not even find myself using non-generic lists for anything anymore unless the type is just object
As others have pointed out, this prevents the need for unboxing.
Because of the different natures of contra-variance and covariance, it can get confusing as to what is and is not acceptable in a generic at times. For instance, if you consider the following layout ..
interface IBase {
}
class Alpha : IBase {
}
class Beta : Alpha {
}
IList<IBase> ListOfObjects { get; set; }
This is confusing. Can you pass both Alpha
and Beta
objects into the list? When I tried it, you couldn't. But then the following worked..
IList<Alpha> ListOfObjects { get; set; }
It accepted both Alpha
and Beta
objects because Beta
inherits Alpha
Take a look at some more information about contravariance and covariance here. It is very useful.
I have never noticed a performance hit from generics. However that does not mean they do not exist. However they are just plain objects, so I cannot see where there would be overhead. In general the compiler should not even let you run code where you are trying to add improper objects to a generic list, and it if does, then you've made a designer error somewhere, or are using dynamics
, or running into an issue of contravariance vs. covariance. Though I do understand that some of this has changed with .NET 4.0.
Upvotes: 3
Reputation: 6442
I don't think the performance difference is significant.
What you really gain by using generics is compile-time checking for the types. It can prevent you from passing an object of the wrong type, for instance (using an object
parameter would result in runtime errors in this case if you are expecting a specific type).
Upvotes: 2