C# 有没有办法将泛型接口约束到实现它的类型? 公共接口可克隆 { T克隆(); } 公共食品:iClonable { 公共Foo克隆() { //废话 } }

C# 有没有办法将泛型接口约束到实现它的类型? 公共接口可克隆 { T克隆(); } 公共食品:iClonable { 公共Foo克隆() { //废话 } },c#,generics,interface,generic-constraints,C#,Generics,Interface,Generic Constraints,有没有办法将T约束到实现接口的类型?(Foo在本例中)。强制任何实现ICloneable的东西都返回自身的实例,而不是它喜欢的任何随机类型,这将是一件好事。基本上不是。使用常规约束无法做到这一点。此外,您不能阻止他们使用不同的t多次实现接口(只要那些t满足任何,其中约束,在这种情况下没有约束) 没有允许对实现类型进行限制的where约束 您可以将其作为方法参数限制来执行,但这并不令人满意: public interface ICloneable<T> { T Clone();

有没有办法将
T
约束到实现接口的类型?(
Foo
在本例中)。强制任何实现ICloneable的东西都返回自身的实例,而不是它喜欢的任何随机类型,这将是一件好事。

基本上不是。使用常规约束无法做到这一点。此外,您不能阻止他们使用不同的
t
多次实现接口(只要那些
t
满足任何
,其中
约束,在这种情况下没有约束)

没有允许对实现类型进行限制的
where
约束

您可以将其作为方法参数限制来执行,但这并不令人满意:

public interface ICloneable<T>
{
    T Clone();
}

public Foo: ICloneable<Foo>
{
    public Foo Clone()
    { 
       //blah
    }
}
publicstatict超克隆(这是T源代码),其中T:ICloneable{…}

基本上没有。使用常规约束无法做到这一点。此外,您不能阻止他们使用不同的
t
多次实现接口(只要那些
t
满足任何
,其中
约束,在这种情况下没有约束)

没有允许对实现类型进行限制的
where
约束

您可以将其作为方法参数限制来执行,但这并不令人满意:

public interface ICloneable<T>
{
    T Clone();
}

public Foo: ICloneable<Foo>
{
    public Foo Clone()
    { 
       //blah
    }
}
publicstatict超克隆(这是T源代码),其中T:ICloneable{…}

请注意,可以使用代码契约来表达这一点。通常在运行时检查,但可能会得到编译时警告(请参阅后面的注释):

事情是这样的:

public static T SuperClone<T>(this T original) where T : ICloneable<T> {...}
这些将导致运行时代码契约失败:

var good = new GoodFoo();
good.Clone();
请注意,您可能会得到编译时警告

如果您执行完整的代码契约静态检查编译,您将看到关于class BadFooclass AlsoBadClone()实现的“确保未经验证”的警告

由于
契约的原因,
GoodFoo.Clone()
没有警告。假定(result.GetType()==this.GetType())在其实现中


但是,代码契约静态检查(在我看来)仍然太慢,除了偶尔检查之外,其他检查都太慢,但是您的里程可能会有所不同……

请注意,可以使用代码契约来表示这一点。通常在运行时检查,但可能会得到编译时警告(请参阅后面的注释):

事情是这样的:

public static T SuperClone<T>(this T original) where T : ICloneable<T> {...}
这些将导致运行时代码契约失败:

var good = new GoodFoo();
good.Clone();
请注意,您可能会得到编译时警告

如果您执行完整的代码契约静态检查编译,您将看到关于class BadFooclass AlsoBadClone()实现的“确保未经验证”的警告

由于
契约的原因,
GoodFoo.Clone()
没有警告。假定(result.GetType()==this.GetType())在其实现中


但是,代码契约静态检查(在我看来)对于除偶尔检查以外的任何检查都太慢,但是您的里程数可能会有所不同……

当您实现ICloneable时,您必须返回Foo或派生的。我在这里遗漏了什么吗?@YuvalItzchakov我相信重点是
Foo
同样容易
:ICloneable
哦,我明白了。感谢您的澄清@Marclavelno。重点是什么?您可以向我展示使用该接口的代码吗?当您实现
ICloneable
时,您必须返回
Foo
或派生代码。我在这里遗漏了什么吗?@YuvalItzchakov我相信重点是
Foo
同样容易
:ICloneable
哦,我明白了。感谢您的澄清@Marclavelno。重点是什么?你能给我看看使用这个接口的代码吗?@AlessandroD'Andria我相信你错了。另见@AlessandroD'Andria,我相信你错了。另见