C# 泛型最酷的地方是什么,为什么要使用它们?
我想我会把这个垒球送给任何想把它打出公园的人。什么是泛型,泛型的优点是什么,为什么,在哪里,我应该如何使用它们?请保持它相当基本。谢谢。泛型允许您创建强类型的对象,但不必定义特定类型。我认为最有用的例子是列表和类似的类C# 泛型最酷的地方是什么,为什么要使用它们?,c#,generics,types,C#,Generics,Types,我想我会把这个垒球送给任何想把它打出公园的人。什么是泛型,泛型的优点是什么,为什么,在哪里,我应该如何使用它们?请保持它相当基本。谢谢。泛型允许您创建强类型的对象,但不必定义特定类型。我认为最有用的例子是列表和类似的类 使用泛型列表,您可以拥有任何您想要的列表,并且您可以始终引用强类型,您不必转换或像使用数组或标准列表那样进行任何转换。泛型避免装箱和取消装箱的性能影响。基本上,看看ArrayList vs List。两者的核心功能相同,但列表速度会快得多,因为您不必在对象之间设置框。泛型允许您对
使用泛型列表,您可以拥有任何您想要的列表,并且您可以始终引用强类型,您不必转换或像使用数组或标准列表那样进行任何转换。泛型避免装箱和取消装箱的性能影响。基本上,看看ArrayList vs List。两者的核心功能相同,但列表速度会快得多,因为您不必在对象之间设置框。泛型允许您对对象和数据结构使用强类型,这些对象和数据结构应该能够容纳任何对象。在从泛型结构(装箱/取消装箱)检索对象时,它还消除了繁琐而昂贵的类型转换
使用这两种方法的一个例子是链表。如果链表类只能使用对象Foo,那么它有什么好处?要实现可处理任何类型对象的链表,如果希望链表仅包含一种类型的对象,则假定节点内部类中的链表和节点必须是泛型的。如果集合包含值类型,当插入到集合中时,它们不需要对对象进行装箱/取消装箱,因此性能会显著提高。像resharper这样很酷的附加组件可以为您生成更多的代码,比如foreach循环。我喜欢它们,因为它们为您提供了一种快速定义自定义类型的方法(因为我一直在使用它们) 例如,不必定义一个由字符串和整数组成的结构,然后必须实现一整套对象和方法来访问这些结构的数组等等,您只需制作一个字典
Dictionary<int, string> dictionary = new Dictionary<int, string>();
Dictionary Dictionary=newdictionary();
编译器/IDE完成了其余的繁重工作。字典特别允许您使用第一种类型作为键(无重复值)。- 允许您编写代码/使用类型安全的库方法,即列表保证为字符串列表
- 由于使用了泛型,编译器可以对代码执行编译时检查,以确保类型安全,也就是说,您是否试图将int放入该字符串列表中?使用ArrayList会导致运行时错误不那么透明
- 比使用对象更快,因为它可以避免装箱/取消装箱(其中.net必须转换)或从对象强制转换为所需的引用类型
- 允许您编写适用于具有相同底层行为的许多类型的代码,即字典使用与字典相同的底层代码;使用泛型,框架团队只需编写一段代码即可实现上述两种结果
List<SomeCustomClass> blah = new List<SomeCustomClass>();
blah[0].SomeCustomFunction();
List blah=newlist();
blah[0]。SomeCustomFunction();
如果没有泛型,您必须将blah[0]强制转换为正确的类型才能访问其函数。jvm仍然强制转换。。。它隐式地创建将泛型类型视为“对象”的代码,并创建所需实例化的强制转换。Java泛型只是语法上的糖。使用泛型(尤其是集合/列表)的另一个优点是可以进行编译时类型检查。这在使用通用列表而不是对象列表时非常有用。最主要的原因是它们提供了类型安全性
List<Customer> custCollection = new List<Customer>;
作为一个简单的例子。总之,泛型允许您更精确地指定要执行的操作(更强的键入) 这对您有几个好处:
- 因为编译器更了解您想要做什么,它允许您省略很多类型转换,因为它已经知道类型将是兼容的
- 这也会让你更早地得到关于你的程序的正确性的反馈。以前在运行时会失败的事情(例如,因为无法将对象转换为所需的类型),现在在编译时失败,您可以在测试部门提交一份神秘的错误报告之前修复错误
- 编译器可以进行更多优化,如避免装箱等
class Pair<F, S> {
public final F first;
public final S second;
public Pair(F f, S s)
{
first = f;
second = s;
}
}
类对{
公开决赛F-first;
公开决赛第二名;
公共对(F、S、S)
{
第一个=f;
秒=秒;
}
}
无论何时使用这个Pair类,您都可以指定希望它处理哪种类型的对象,并且任何类型转换问题都将在编译时而不是运行时出现
泛型也可以用关键字“super”和“extends”定义其边界。例如,如果你想要dea
class Pair<F, S> {
public final F first;
public final S second;
public Pair(F f, S s)
{
first = f;
second = s;
}
}
public class FooManager <F extends Foo>{
public void setTitle(F foo, String title) {
foo.setTitle(title);
}
}
public interface IEntity
{
}
public class Employee : IEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeID { get; set; }
}
public class Company : IEntity
{
public string Name { get; set; }
public string TaxID { get; set }
}
public class DataService<ENTITY, DATACONTEXT>
where ENTITY : class, IEntity, new()
where DATACONTEXT : DataContext, new()
{
public void Create(List<ENTITY> entities)
{
using (DATACONTEXT db = new DATACONTEXT())
{
Table<ENTITY> table = db.GetTable<ENTITY>();
foreach (ENTITY entity in entities)
table.InsertOnSubmit (entity);
db.SubmitChanges();
}
}
}
public class MyTest
{
public void DoSomething()
{
var dataService = new DataService<Employee, MyDataContext>();
dataService.Create(new Employee { FirstName = "Bob", LastName = "Smith", EmployeeID = 5 });
var otherDataService = new DataService<Company, MyDataContext>();
otherDataService.Create(new Company { Name = "ACME", TaxID = "123-111-2233" });
}
}
public abstract class GenericDaoHibernateImpl<T>
extends HibernateDaoSupport {
private Class<T> type;
public GenericDaoHibernateImpl(Class<T> clazz) {
type = clazz;
}
public void update(T object) {
getHibernateTemplate().update(object);
}
@SuppressWarnings("unchecked")
public Integer count() {
return ((Integer) getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) {
// Code in Hibernate for getting the count
}
}));
}
.
.
.
}
public class UserDaoHibernateImpl extends GenericDaoHibernateImpl<User> {
public UserDaoHibernateImpl() {
super(User.class); // This is for giving Hibernate a .class
// work with, as generics disappear at runtime
}
// Entity specific methods here
}
List<Stuff> stuffList = getStuff();
for(Stuff stuff : stuffList) {
stuff.do();
}
List stuffList = getStuff();
Iterator i = stuffList.iterator();
while(i.hasNext()) {
Stuff stuff = (Stuff)i.next();
stuff.do();
}
List stuffList = getStuff();
for(int i = 0; i < stuffList.size(); i++) {
Stuff stuff = (Stuff)stuffList.get(i);
stuff.do();
}
public class Foo
{
public string Bar() { return "Bar"; }
}
Arraylist al = new ArrayList();
List<Foo> fl = new List<Foo>();
//code to add Foos
al.Add(new Foo());
f1.Add(new Foo());
foreach(object o in al)
{
Foo f = (Foo)o;
f.Bar();
}
foreach(Foo f in fl)
{
f.Bar();
}
class MyObjectList {
MyObject get(int index) {...}
}
class MyOtherObjectList {
MyOtherObject get(int index) {...}
}
class AnotherObjectList {
AnotherObject get(int index) {...}
}
class MyList<T> {
T get(int index) { ... }
}
private <T extends Throwable> T logAndReturn(T t) {
logThrowable(t); // some logging method that takes a Throwable
return t;
}
...
} catch (MyException e) {
throw logAndReturn(e);
}
...
Map<String, Integer> myMap = createHashMap();
...
public <K, V> Map<K, V> createHashMap() {
return new HashMap<K, V>();
}
Map<String, Integer> m = new HashMap<String, Integer>();
Set<Integer> set = new HashSet<Integer>();
set.add(10);
set.add(42);
int total = 0;
for (int i : set) {
total += i;
}
set.add(10);
set.add(42);
for (int i : set) {
total += i;
}
Set set = new HashSet();
set.add(10);
set.add(42);
int total = 0;
for (Object o : set) {
total += (Integer)o;
}
set.add(10);
set.add(42);
for (Object o : set) {
total += (Integer)o;
public interface F<A, B> {
public B f(A a);
}
F<Integer, String> intToString = new F<Integer, String>() {
public String f(int i) {
return String.valueOf(i);
}
}
public final class Hash<A> {
private final F<A, Integer> hashFunction;
public Hash(final F<A, Integer> f) {
this.hashFunction = f;
}
public int hash(A a) {
return hashFunction.f(a);
}
}
public interface Foo<T extends MyObject> extends Hoo<T>{
...
}
public <T extends MyObject> foo(T t1, T t2){
...
}