接口作为参数或泛型方法在哪里-有什么区别

本文关键字:什么 区别 在哪里 泛型方法 参数 接口 | 更新日期: 2023-09-27 18:17:00

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

public void Method2(class1 c, Imyinterface obj)

?

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

接口作为参数或泛型方法在哪里-有什么区别

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

如果你看一下幕后,你会发现对于泛型方法,. net将为你调用它的每种类型编译一个单独的方法。这可以避免在使用struct调用时装箱。

使用返回类型时,最大的区别就出现了。

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;
}

假设老虎实现了ICanMove和ICanPounce,老鹰实现了ICanMove和ICanFly,我可以调用上面应用于原始类型的扩展方法。智能感知将显示。fly()和。move()适用于鹰,。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接口,编译器不知道它原来是Eagle还是Tiger,所以你只能使用属于ICanMove接口的扩展、方法或属性。

使用泛型方法可以通过轻微的签名更改提供各种可能性:

  1. public void Method1<T>(class1 c, T obj) where T:Imyinterface, new():
    这允许实例化类型为T的新实例
  2. public T Method1<T>(class1 c, T obj) where T:Imyinterface:
    这允许您在需要时使用该方法而不强制转换其返回值。
  3. public void Method1<T>(class1 c, ref T obj) where T:Imyinterface:
    这允许您向obj的引用传递一个新值。同样适用于out

这些对于非通用版本是不可能的。

在您的场景中,它实际上是相同的(除了使用接受接口参数的方法将具体对象上推为接口类型),请考虑稍微不同的场景。假设我们希望我们的方法只接受实现IMyInterface1IMyInterface2两个接口的类,否则代码不应该编译:

interface IMyInterface1 { }    
interface IMyInterface2 { }
class MyClass : IMyInterface1 { }
public void Method1<T>(Class1 c, T obj) where T : IMyInterface1, IMyInterface2
{
}

如果我们创建的方法接受interface作为它的第二个参数,它将不满足条件,因为它不限制用户发送只实现一个接口的类实例,但不像这个例子中MyClass和IMyInterface2那样实现第二个接口。

用户应该发送什么界面?他并不真正知道需要在编译时发送的类型。

这是使用泛型和泛型约束的好地方,另一方面,我们不能使用单个接口参数

void方法之间差异不大

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

=

public void Method2(class1 c, Imyinterface obj, Type t)

其中t必须为Imyinterface

所以如果你需要传递一些Type给你的方法,你需要在编译时对Type应用一些约束,使用泛型方法。