我正在尝试生成一些类似下面的方法,添加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);
}
}
}
}发布于 2011-06-05 02:37:32
除了我的帖子解释了一些关于泛型的事情之外,你的情况看起来并不是真的需要它们。相反,您应该向您的类添加一个属性。
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" ) );。
发布于 2011-06-05 00:09:37
据我所知,大多数使用泛型的操作都是在IL级别进行的,因此不会对性能造成太大影响。它所做的一切就是强制和检查对象是特定类型的。最大的缺点是对逆变和协方差的理解。这里有一些关于它的文章。
文章
Using Variance in Interfaces for Generic Collections
Covariance and Contravariance FAQ (.NET 4.0 Updated)
优点
使用泛型,您可以在运行时和设计时都获得类型安全。您能够实时接收有关对象的intellisense,就好像它们是为特定类型硬编码的一样。这在设置两种扩展方法和...well几乎所有其他方法时都非常有用。事实上,从.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
看看关于逆方差和协方差here的更多信息。它非常有用。
我从来没有注意到泛型对性能的影响。然而,这并不意味着它们不存在。然而,它们只是普通的对象,所以我看不到哪里会有开销。一般来说,编译器甚至不应该让你在试图将不适当的对象添加到泛型列表中的地方运行代码,如果这样做了,那么你就在某个地方犯了设计器错误,或者正在使用dynamics,或者遇到了逆变和协变的问题。不过,我确实理解,在.NET 4.0中,这一点有所改变。
发布于 2011-06-05 00:01:39
我不认为性能差异是显著的。
通过使用泛型,您真正获得的是类型的编译时检查。例如,它可以防止您传递错误类型的对象(在这种情况下,如果您需要特定类型,则使用object参数将导致运行时错误)。
https://stackoverflow.com/questions/6237779
复制相似问题