我正在努力寻找一种将非泛型接口用作泛型类型约束的方案。下面是一个任意的例子,其中非泛型方法(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"); }
}
很明显,RideCar2是一个更好的实现,因为它具有更少的噪音。
是否存在使用非泛型接口作为泛型类型约束的情况?
进一步举例(根据回复)
static T RideCar(T t) where T : ICar
{
t.StartEngine();
t.StopEngine();
return t;
}
使用普通方法仍然无法使用通用方法,请参阅下文:
static ICar RideCar(ICar car)
{
car.StartEngine();
car.StopEngine();
return car;
}
static void RideCar(T t) where T : ICar, ICanTimeTravel
{
t.StartEngine(); // ICar
t.TravelToYear(1955); // ICanTimeTravel
t.StopEngine(); // ICar
}
使用具有多个参数的常规方法仍然会使用通用方法无用,请参阅下文:
static void RideCar(ICar car, ICanTimeTravel canTimeTravel)
{
car.StartEngine();
canTimeTravel.TravelToYear(1955);
car.StopEngine();
}
答案 0 :(得分:5)
是的,有。考虑:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<img id="image" src="http://i.stack.imgur.com/gTiMi.png" usemap="#Map" >
<map name="Map">
<area data-number="1" class="area" shape="rect" coords="5,5,35,30" href="#">
<area data-number="2" class="area" shape="rect" coords="50,5,75,30" href="#">
<area data-number="9" class="area" shape="rect" coords="90,5,115,30" href="#">
<area data-number="7" class="area" shape="rect" coords="130,5,155,30" href="#">
<area data-number="3" class="area" shape="rect" coords="170,5,195,30" href="#">
<area data-number="0" class="area" shape="rect" coords="5,50,35,75" href="#">
<area data-number="5" class="area" shape="rect" coords="50,50,75,75" href="#">
<area data-number="4" class="area" shape="rect" coords="90,50,115,75" href="#">
<area data-number="8" class="area" shape="rect" coords="130,50,155,75" href="#">
<area data-number="6" class="area" shape="rect" coords="170,50,195,75" href="#">
</map>
这将返回特定类型。现在您可以使用实现细节而不必将其强制转换为实现类型,这是不好的做法。
此外,您可以对同一个通用参数设置多个接口约束:
static T RideCar<T>(T t) where T : ICar
{
t.StartEngine();
t.StopEngine();
return t;
}
最后,即使有时被认为是代码味道,您也可以使用static void RideCar<T>(T t) where T : ICar, ICanTimeTravel
{
t.StartEngine(); // ICar
t.TravelToYear(1955); // ICanTimeTravel
t.StopEngine(); // ICar
}
约束和接口约束,以便在方法中创建实现类型的实例:
new()
答案 1 :(得分:0)
这取决于。在您的情况下,首选非通用方式。
如果要调用在不同接口上声明的方法,那么带有类型约束的泛型声明是有意义的:
[Row(id_sa=a1, max_id_sb=b2),
Row(id_sa=a2, max_id_sb=b2)]
但在这种情况下,如果可能的话,我更喜欢使用基类,并在没有任何类型约束的情况下在以下方法中使用它:
public void Test<T>(T value, T other)
where T: IEquatable<T>, IComparable<T>
{
value.Equals(other); //in IEquatable<T>
value.CompareTo(other); //in IComparable<T>
}
或没有泛型,但限于ICar:
public class BaseCar<T> : IEquatable<T>, IComparable<T>, ICar
{
/// [...]
}
public void Test<T>(BaseCar<T> car1, BaseCar<T> car2)
where T: IEquatable<T>, IComparable<T>
{
car1.Equals(car2);
car1.CompareTo(car2);
}