使用泛型实现显式接口成员

发布于 2024-12-07 04:35:29 字数 1464 浏览 1 评论 0原文

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

因此,基本上通过此设置,我有许多类,例如 ActualThing1ActualThing2。这些类有一个 Clone 方法,该方法返回它们自身的强类型克隆。

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

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

但是该代码(抛出异常的地方)永远无法执行,不是吗,因为我没有该对象的任何非通用实现?

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

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

I have a nongeneric interface to a generic class group. I have a method which uses covariance to return a strongly typed instance in a class derived from an abstract implementation of the non-generic class group.

So basically with this setup, I have a number of classes, e.g. ActualThing1 and ActualThing2. These classes have a Clone method which returns a strongly-typed clone of themselves.

Below is how I've structured the interface & classes. I am not sure this is right.
Normally, I wouldn't have the non-generic abstract class at all. But this is necessary because there is a situation where I have to do something to child objects, referencing an internal method _SomethingNeededInternally. This can't be done using the interface, since it's protected, nor can it be done from inside the generic class, since the children might not be the same type (they might be a different type derived from the interface). Hence the non-generic base class Something.

This works, but what doesn't quite make sense to me is the explicit implementation of ISomething.Clone that is needed in my abstract Something class. It has to be there, but it shouldn't be implemented, since I want that implementation deferred to the generic class that derives from it. But there's no such syntax as abstract ISomething ISomething.Clone().

But that code (where the exception is throw) can't ever execute, can it, since I don't have any non-generic implementations of this object?

I guess I'm wondering if there is a better way to do this, because it seems not right. That is, I am depending on the fact that a non-generic class is never created from the interface, which smells funny.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

山川志 2024-12-14 04:35:29

添加所需的方法作为 Clone 的实现对您有用吗?
(我仍然不确定你的整个问题是什么,这只会解决抽象显式接口实现的语法。)

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

Would adding required method as implementation of Clone work for you?
(I'm still not exactly sure what your whole problem is, this will just solve syntax for abstract explicit interface implementation.)

public abstract class Something: ISomething  
{ 
    ISomething ISomething.Clone() 
    { 
        return CloneYouMust();
    } 
    abstract ISomething CloneYouMust();
}
笑梦风尘 2024-12-14 04:35:29

我认为这可能会更好:

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() 
    {
    }
}

I think this might work better:

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() 
    {
    }
}
苯莒 2024-12-14 04:35:29

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

Your complaint about abstract ISomething ISomething.Clone is valid but there's nothing about interfaces that states you must explicitly declare them. The code below shows a working example and removes the requirement of the generic class.

interface Igloo
{
    Igloo Clone();
}

abstract class Alpha : Igloo
{
    public abstract Igloo Clone();
}

class Bravo : Alpha
{
    public override Igloo Clone()
    {
        /* implement */
        return null;
    }
}
旧夏天 2024-12-14 04:35:29

首先,我认为 Something中有两个 Clone() 方法。是多余的。既然您已经将 T 限制为 ISomething 和 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
    }     
} 

其次,我不完全清楚 _SomethingNeededInternally 是否需要是抽象的或虚拟的,但它也没有标记。我的解释是它应该是虚拟的,但也许你需要调整它。无论如何,这是一个对我来说似乎很有效并且最有意义的总体方案。请注意,我能够在抽象类“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”类中将返回类型标记为 ISomething。当然,实际上您会返回一个“ActualThing”,但该方法仍然需要符合接口。

First of all, I think that having two Clone() methods inside Something<T> is redundant. Since you've already constrained T to both being an ISomething and new(), why not do this:

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

Secondly I'm not entirely clear on whether _SomethingNeededInternally needs to be abstract or virtual, but it isnt marked either. My interpretation is that it should be virtual, but maybe you'll need to tweak that. Anyway here is the overall scheme that seems to work well for me and make the most sense. Note that I was able to make the Clone() method abstract in the abstract class 'Something':

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

Also note that you need to mark the return type as ISomething in the final 'ActualThing' class. Of course you would be returning an 'ActualThing' in reality, but the method needs to conform to the interface nevertheless.

野却迷人 2024-12-14 04:35:29

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

I would suggest that you define and implement interfaces ISelf<T>, containing a single Self property of type T, and ICloneable<out T>, deriving from ISelf<T>, with a method Clone() of type T. Then a class which implements ICloneable<ItsOwnType> can implement it with a method returning ItsOwnType; that method should call then a virtual InternalClone method to do the actual work (otherwise, calling Clone on a variable of base type might end up calling the base-type Clone method rather than a derived one).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文