C# 接口能否定义基于实现者类进行区分的函数?

C# 接口能否定义基于实现者类进行区分的函数?,c#,.net,interface,C#,.net,Interface,我试图定义一个接口,该接口的函数只接受实现它的类类型。以下是我到目前为止的情况: public interface ICombinableAction : IAction { public bool CombineActions(ICombinableAction toCombine); } public class MoveAllObjects : ICombinableAction { public bool CombineActions(ICombinableAction

我试图定义一个接口,该接口的函数只接受实现它的类类型。以下是我到目前为止的情况:

public interface ICombinableAction : IAction {
    public bool CombineActions(ICombinableAction toCombine);
}

public class MoveAllObjects : ICombinableAction {
    public bool CombineActions(ICombinableAction toCombine) {
        if (!(toCombine is MoveAllObjects)) {
            // This isn't possible, inform the caller
            return false;
        }
        ... // Combining logic
        return true;
    }
}
不幸的是,由于函数无法在compiletime检查传入的对象的类型,因此我必须处理使用不兼容类的情况,然后在调用方中处理该情况

理想情况下,通过定义接口,使同一类的实例只可能存在,这是可能的,大致如下:

public interface ICombinableAction : IAction {
    public void CombineActions(Implementor toCombine);
}

public class MoveAllObjects : ICombinableAction {
    public void CombineActions(MoveAllObjects toCombine) {
        ... // Combining logic
    }
}
我怀疑这是不可能的,因为有一个问题。我怀疑这个问题也围绕着我现在的问题。但这两个问题都没有帮助我找到解决我的问题的方法


在这种情况下,什么是一个好的解决方案?

如果我正确理解了您的问题,您可以通过泛型实现以下目标:

public interface ICombinableAction<T> where T : ICombinableAction<T>
{
    public void CombineActions(T toCombine);
}

public class MoveAllObjects : ICombinableAction<MoveAllObjects>
{
    public void CombineActions(MoveAllObjects toCombine)
    {

    }
}
公共接口图标组合,其中T:ICombinableAction
{
公共空间组合(T组合);
}
公共类MoveAllObjects:ICombinableAction
{
公共无效组合(将所有对象移动到组合)
{
}
}

如果我正确理解了您的问题,您可以通过泛型实现以下目标:

public interface ICombinableAction<T> where T : ICombinableAction<T>
{
    public void CombineActions(T toCombine);
}

public class MoveAllObjects : ICombinableAction<MoveAllObjects>
{
    public void CombineActions(MoveAllObjects toCombine)
    {

    }
}
公共接口图标组合,其中T:ICombinableAction
{
公共空间组合(T组合);
}
公共类MoveAllObjects:ICombinableAction
{
公共无效组合(将所有对象移动到组合)
{
}
}

此方法的一个潜在问题是,如果您想要一个
列表
,其中T对于要放入列表中的一个或多个元素是不同的。@JacobHuckins是的,有效点,但这可以通过非泛型版本的接口解决。另外,如果OP想要编译时安全,那么这样的集合有多少意义呢?啊,这看起来正是我所需要的。以前没有玩过泛型,我想我还有别的事情要调查!所以我有一个列表,但是它是
IAction
(它是
ICombinableAction
实现的),所以希望这应该意味着它可以很好地工作。如果接口必须引用基类型,我不知道它有什么好处。这并没有按照要求实现
ICombinableAction
,而是实现
ICombinableAction
。为什么要有一个接口呢?为什么不让
MoveAllObjects.CombineActions(MoveAllObjects)
?我不明白这能带来什么。你能举个用法的例子吗?特别是,您能否演示命名协变接口而不命名基类所需的参数协变性?@Malrig您似乎只需要将检查添加到接口
bool CombinableWith(ICombinableAction other)
,不必麻烦使用泛型。此方法的一个潜在问题是,如果您想要一个
列表,其中t对于要放入列表中的一个或多个元素是不同的。@JacobHuckins是的,有效点,但这可以通过非泛型版本的接口解决。另外,如果OP想要编译时安全,那么这样的集合有多少意义呢?啊,这看起来正是我所需要的。以前没有玩过泛型,我想我还有别的事情要调查!所以我有一个列表,但是它是
IAction
(它是
ICombinableAction
实现的),所以希望这应该意味着它可以很好地工作。如果接口必须引用基类型,我不知道它有什么好处。这并没有按照要求实现
ICombinableAction
,而是实现
ICombinableAction
。为什么要有一个接口呢?为什么不让
MoveAllObjects.CombineActions(MoveAllObjects)
?我不明白这能带来什么。你能举个用法的例子吗?特别是,您能否演示命名协变接口而不命名基类所需的参数协变性?@Malrig您似乎只需要将check添加到接口
bool-CombinableWith(ICombinableAction-other)
,而不必麻烦使用泛型。