用泛型实现显式接口成员

本文关键字:接口 成员 泛型 实现 | 更新日期: 2023-09-27 18:10:01

我有一个到泛型类组的非泛型接口。我有一个方法,它使用协方差来返回从非泛型类组的抽象实现派生的类中的强类型实例。

所以基本上有了这个设置,我有很多类,例如ActualThing1ActualThing2。这些类有一个Clone方法,它返回自己的强类型克隆。

下面是我如何构建接口&类。我不确定这是对的。通常,我根本不会有非泛型抽象类。但这是必要的,因为有一种情况,我必须做一些子对象,引用一个内部方法_SomethingNeededInternally。这不能使用接口来完成,因为它是受保护的,也不能在泛型类中完成,因为子类可能不是相同的类型(它们可能是从接口派生的不同类型)。因此非泛型基类Something

这是有效的,但对我来说不太有意义的是在我的抽象Something类中需要的ISomething.Clone的显式实现。它必须在那里,但它不应该被实现,因为我希望实现延迟到从它派生的泛型类。但是没有abstract ISomething ISomething.Clone()这样的语法。

但是这段代码(异常是throw)永远不能执行,因为我没有这个对象的任何非泛型实现?

我想我想知道是否有更好的方法来做到这一点,因为它似乎是不对的。也就是说,我依赖于这样一个事实,即永远不会从接口创建非泛型类,这听起来很有趣。

public interface ISomething
{
    // ...
    ISomething Clone();
}
public abstract class Something: ISomething 
{
    ISomething ISomething.Clone()
    {
        throw new Exception("This should not be happening");
    }
    protected int _SomethingNeededInternally;
}
public abstract class Something<T>: Something, ISomething where T: ISomething, new()
{
    public abstract T Clone();
    ISomething ISomething.Clone()
    {
        return Clone();
    }
}
public interface IActualThing {} // this could be any interface
public class ActualThing: Something<ActualThing>, IActualThing
{
    public override ActualThing Clone() 
    {
        return new ActualThing(); // do cloning here
    }
}

用泛型实现显式接口成员

添加所需的方法作为克隆工作的实现为您服务吗?(我仍然不确定你的整个问题是什么,这将只是解决抽象显式接口实现的语法。)

public abstract class Something: ISomething  
{ 
    ISomething ISomething.Clone() 
    { 
        return CloneYouMust();
    } 
    abstract ISomething CloneYouMust();
}

我认为这可能会更好:

public interface ISomething
{
    ISomething Clone();
}
public abstract class Something : ISomething 
{
    protected abstract ISomething CloneInternal();
    ISomething ISomething.Clone()
    {
        return CloneInternal();
    }
}
public abstract class Something<T>: Something, ISomething where T: ISomething, new()
{
    protected override ISomething CloneInternal()
    {
        return Clone();
    }
    public abstract T Clone();
}
public class ActualThing: Something<ActualThing>, IActualThing
{
    public override ActualThing Clone() 
    {
    }
}

你对abstract ISomething ISomething.Clone的抱怨是有效的,但是没有任何关于接口的规定你必须显式地声明它们。下面的代码显示了一个工作示例,并删除了对泛型类的要求。

interface Igloo
{
    Igloo Clone();
}
abstract class Alpha : Igloo
{
    public abstract Igloo Clone();
}
class Bravo : Alpha
{
    public override Igloo Clone()
    {
        /* implement */
        return null;
    }
}

首先,我认为在Something中有两个Clone()方法是多余的。既然已经将T约束为issomething和new(),为什么不这样做呢:

public abstract class Something<T>: Something, ISomething 
       where T: ISomething, new() 
{     
    public override ISomething Clone()    
    {
        return new T().Clone(); 
        //alternatively may have to use Activator.CreateInstance() here
    }     
} 

其次,我不完全清楚_somethingneeddedinternal是否需要抽象或虚拟,但它也没有标记。我的解释是,它应该是虚拟的,但也许你需要调整一下。无论如何,这是一个整体方案,似乎对我来说效果很好,而且最有意义。请注意,我能够在抽象类'Something'中使Clone()方法抽象:

public interface IActualThing
{
}
public interface ISomething 
{    
    ISomething Clone(); 
}  
public abstract class Something: ISomething  
{
    public abstract ISomething Clone();
    protected virtual void _SomethingNeededInternally()
    {
        throw new NotImplementedException(); 
    }
}  
public abstract class Something<T>: Something, ISomething where T: ISomething, new()
{    
    public override ISomething Clone()    
    {
        return new T().Clone(); 
    } 
}  
public class ActualThing: Something<ActualThing>, IActualThing 
{     
    public override ISomething Clone()      
    {
        throw new NotImplementedException(); 
    }
} 

还要注意,你需要在最后的'ActualThing'类中将返回类型标记为issomething。当然在现实中你会返回一个'ActualThing',但是方法需要遵从接口。

我建议你定义并实现接口ISelf,它包含一个类型为T的Self属性,以及从ISelf派生的ICloneable和一个类型为T的Clone()方法,然后一个实现ICloneable可以用一个返回ItsOwnType的方法来实现;该方法应该调用一个虚拟的InternalClone方法来完成实际的工作(否则,在基类型的变量上调用Clone可能最终调用基类型的Clone方法,而不是派生的Clone方法)。