关于课程
这个问题与以下问题大致相同:非泛型ArrayList
和泛型之间有什么区别List<T>
。由于 ArrayList 接受任何类型的数据(都是来自基类的服务object
,因此很容易将数据取出。
有一个很大的缺点:当您从 中提取数据时ArrayList
,您必须将其转换回其原始数据类型。
在你的例子中,同样的事情。假设您有一个经理班:
public class Manager : Employee {}
你创建到列表:
public class MyList: List<Emplyoyee> {}
public class MyList<T>: List<T> where T : Employee {}
...
MyList myList1 = ...;
MyList<Employee> myList2 = ...;
myList1
和willa 都myList2
接受Employee
实例和Manager
实例。到目前为止没有区别。(这与比较ArrayList
和相同List<object>
。)
但现在试试这个:
MyList myList1 = ...;
MyList<Manager> myList2 = ...;
两个列表都接受该Manager
类型的实例。但myList1
也只接受 type 的实例Employee
。如果您想从您那里检索经理,myList1
您可能需要强制转换它(性能下降)。myList2
仅限于接受经理(和衍生品)。
简而言之:MyList
可以用于任何 Employee-derivative 并且不像MyList<T>
. MyList<T>
只要它派生自 ,就可以恢复为任何类型Employee
。它
如果您不打算为经理制定专门的清单,那么在这种情况下不会有任何区别。
关于方法
您的方法示例都有点相同。让我们用一些其他的例子来演示使用:
void DoSomething1(object value) {};
void DoSomething2<T>(T value) {};
两种方法都接受 ANY 参数。例外,如果您将值类型用于DoSomething1
,则该值将被装箱。拳击是一种性能损失。DoSomething2
会根据自己的类型进行调整。因此:
DoSomething1(123); // <-- Will box the int.
DoSomething2(123); // <-- Will NOT box the int.
另一个例子:
object Copy1(object value) {};
T Copy2<T>(T value) {};
两种方法都会复制参数并将其返回(如何,现在无关紧要)。在第一个示例中,object
返回 an。如果您想使用该副本,则必须先投射它。也许拆箱。两者性能损失。在第二个 Copy 方法中,您总是得到与参数相同类型的返回值。因此:
int copy1 = (int)Copy1(123); // <-- Will box the int, and the copy needs to be unboxed.
int copy2 = Copy2(123); // <-- Will NOT box the int, and the copy does NOT need to be unboxed or casted.
在您的情况下,当您仅使用作为引用类型而不是返回类型的输入参数时,它不会有太大的不同(关注性能)。