c# - 接口(interface)作为参数或泛型方法与 where - 有什么区别?

标签 c# generics

有什么区别:

public void Method1<T>(class1 c, T obj) where T:Imyinterface

public void Method2(class1 c, Imyinterface obj)

?

使用第一种方法有什么好处?

最佳答案

如前所述,void 方法在用法上没有太大区别。

如果您查看幕后,您会发现使用泛型方法时,.NET 将为您调用它的每种类型编译一个单独的方法。这具有在使用结构调用时避免装箱的效果。

当您使用返回类型时,会出现很大的不同。

public T Method1<T>(class1 c, T obj) where T: IMyInterface

public IMyinterface Method2(class1 c, IMyInterface obj)

使用泛型版本,您可以获得原始类型,因此您可以继续调用原始类型的属性或方法(实例或扩展)。

使用非泛型版本,您只能返回一个 IMyInterface 类型的值,因此您只能调用属于 IMyInterface 的属性或方法.

在我的书中,这是最有趣的,当与扩展方法和流畅风格的 API 一起使用时。

public static T Move<T>(this T animal) where T : ICanMove
{
    return animal;
}

public static T Fly<T>(this T animal) where T : ICanFly
{
    return animal;
}

public static T Pounce<T>(this T animal) where T : ICanPounce
{

    return animal;
}

鉴于 Tiger 实现了 ICanMove 和 ICanPounce,而 Eagle 实现了 ICanMove 和 ICanFly,我可以调用适用于原始类型的上述扩展方法。 Intellisense 将显示适用于 Eagle 的 .Fly() 和 .Move(),以及适用于 Tiger 的 .Pounce() 和 .Move()。

var birdie = new Eagle();

birdie
    .Move()
    .Fly()
    .Move()
    .Fly();

var kitty = new Tiger();

kitty
    .Move()
    .Pounce()
    .Move()
    .Pounce();

如果您非一般地实现 Move,它会是这样的:

public static ICanMove Move<T>(this ICanMove animal) 
{
    return animal;
}

由于返回了 ICanMove 接口(interface),编译器不知道它最初是 Eagle 还是 Tiger,因此您只能使用属于 ICanMove 接口(interface)的扩展、方法或属性。

关于c# - 接口(interface)作为参数或泛型方法与 where - 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33040621/

相关文章:

c# - IEnumerable 是否必须使用 Yield 才能延迟

c# - 使用无操作 lambda 表达式来初始化事件是否会阻止 GC?

generics - 不能使用R作为化类型参数使用抽象类Kotlin中的类代替

java - 继承层次结构改变以减少代码重复

swift - 在方法中使用类作为泛型类型参数

c# - 使用 OWIN 在 ASP.NET MVC 5 应用程序中存储和检索 facebook 访问 token

c# - 使用 xamarin 从现有 wpf 程序创建 Linux 应用程序

c# - 如何在不指定任何类型参数的情况下创建构造泛型类型

Java 泛型 : What is the compiler's issue here? ("no unique maximal instance")

c# - C# 中的密集图形应用程序(使用 .NET/Mono)