何时使用非泛型接口作为泛型类型约束

Dan*_*ral 1 c# generics interface

我正在努力寻找一种使用非泛型接口作为泛型类型约束的方案.下面是一个任意的例子,其中非泛型方法(RideCar2)比泛型方法RideCar简单.

class Program
{
    static void Main(string[] args)
    {
        var car = new Merc();
        RideCar(car);
        RideCar2(car);
    }

    static void RideCar<T>(T t) where T : ICar
    {
        t.StartEngine();
        t.StopEngine();
    }

    static void RideCar2(ICar car)
    {
        car.StartEngine();
        car.StopEngine();
    }
}

public interface ICar
{
    void StartEngine();
    void StopEngine();
}

public class Merc : ICar
{
    public void StartEngine() { Console.WriteLine("Merc start"); }
    public void StopEngine() { Console.WriteLine("Merc stop"); }
}
Run Code Online (Sandbox Code Playgroud)

很明显RideCar2是一个更好的实现,因为它具有更少的噪音.

是否存在使用非泛型接口作为泛型类型约束的情况?

更进一步的例子(根据答复)

  1. 用作返回类型

static T RideCar(T t) where T : ICar
{
    t.StartEngine();
    t.StopEngine();
    return t;
}
Run Code Online (Sandbox Code Playgroud)

使用普通方法仍然无法使用泛型方法,请参见下文:


static ICar RideCar(ICar car)
{
 car.StartEngine();
 car.StopEngine();
 return car;
}
Run Code Online (Sandbox Code Playgroud)
  1. 多个接口

static void RideCar(T t) where T : ICar, ICanTimeTravel
{
    t.StartEngine();      // ICar
    t.TravelToYear(1955); // ICanTimeTravel
    t.StopEngine();       // ICar
}
Run Code Online (Sandbox Code Playgroud)

使用具有多个参数的常规方法仍然使用通用方法无用,请参见下文:


static void RideCar(ICar car, ICanTimeTravel canTimeTravel)
{
 car.StartEngine();
 canTimeTravel.TravelToYear(1955);
 car.StopEngine();
}
Run Code Online (Sandbox Code Playgroud)

Ged*_*tis 5

就在这里.考虑:

static T RideCar<T>(T t) where T : ICar
{
    t.StartEngine();
    t.StopEngine();
    return t;
}
Run Code Online (Sandbox Code Playgroud)

这将返回特定类型.现在您可以使用实现细节而不必将其强制转换为实现类型,这是不好的做法.

此外,您可以对同一个泛型参数有多个接口约束:

static void RideCar<T>(T t) where T : ICar, ICanTimeTravel
{
    t.StartEngine();      // ICar
    t.TravelToYear(1955); // ICanTimeTravel
    t.StopEngine();       // ICar
}
Run Code Online (Sandbox Code Playgroud)

最后,即使这有时被视为代码味道,您也可以使用new()约束和接口约束,以便在方法内创建实现类型的实例:

static T Create<T>() where T : ICar, new()
{
    T t = new T();
    return t;
}
Run Code Online (Sandbox Code Playgroud)