为参数指定多个接口

31

我有一个实现了两个接口的对象...这两个接口分别是:

public interface IObject
{
    string Name { get; }
    string Class { get; }
    IEnumerable<IObjectProperty> Properties { get; }
}
public interface ITreeNode<T>
{
    T Parent { get; }
    IEnumerable<T> Children { get; }
}

以至于
public class ObjectNode : IObject, ITreeNode<IObject>
{
    public string Class { get; private set; }
    public string Name { get; private set; }
    public IEnumerable<IObjectProperty> Properties { get; set; }
    public IEnumerable<IObject> Children { get; private set; }
    public IObject Parent { get; private set; }
}

现在我有一个函数,它需要一个参数来实现这两个接口。在C#中,我该如何指定?

一个例子如下:

public TypedObject(ITreeNode<IObject> baseObject, IEnumerable<IType> types, ITreeNode<IObject>, IObject parent)
{
    //Construct here
}

或者问题在于我的设计有误,我应该以某种方式在一个接口上实现这两个接口。


1
现在我有一个函数,它需要其中一个参数来实现这两个接口。函数或参数不会实现接口,类实现接口。你的意思是什么? - McKay
我知道只有类可以实现接口。 - TerrorAustralis
可能是重复的问题:是否可以使参数实现两个接口? - Robert MacLean
4个回答

51
public void Foo<T>(T myParam)
    where T : IObject, ITreeNode<IObject>
{
    // whatever
}

这是一个很好的答案。我意识到我漏掉了一些关键信息。我所指的函数是另一个类的构造函数(场景是一个节点构建另一个节点)。泛型能在构造函数中使用吗? - TerrorAustralis
2
既然这个答案对我的问题有效,我会接受它,但构造函数的事情让我头疼 :) - TerrorAustralis
在这种情况下,我认为您必须使类成为通用的。看起来您不能在非通用类上拥有通用构造函数。 - Tara McGrew
好的方法解决方案。不幸的是,如果不将整个类泛化,很难将此解决方案应用于属性。 - AgostinoX
1
@AgostinoX 确实。属性的值必须具有单一类型。您可以选择一个接口作为属性类型,并使setter验证该值也实现了另一个接口,但getter无法表示它将始终返回实现两个接口的值。(这就是Code Contracts擅长的事情。) - Tara McGrew
显示剩余2条评论

14

在C#中,接口本身可以从一个或多个其他接口继承而来。因此,一种解决方案是定义一个接口,比如说IObjectTreeNode<T>,它从IObjectITreeNode<T>两个接口派生而来。


9
这将改变需求。这种方法不需要参数实现IObject和ITreeNode<T>,而是需要参数实现IObjectTreeNode<T>。因此,虽然允许同时实现这两个接口但不是合并后的接口的对象将不被允许,但它们应该是可以的。 - Stijn Van Antwerpen

3

最简单的方式可能是定义一个实现IObject和ITreeNode的接口。

public interface IObjectNode<T> : IObject, ITreeNode<T>
{
}

如果您不希望上述接口经常使用,另一个选择是使涉及的方法/函数通用。

public void Foo<T>(T objectNode) where T : IObject, ITreeNode<IObject>

5
这只是重复之前的答案,并没有承认Stijn在评论中指出的第一种方法的缺点。 - Mark Amery

-5
public  void MethodName<TParam1, TParam2>(TParam1 param1, TParam2 param2) 
    where TParam1 : IObject
    where TParam2 : ITreeNode<IObject> 

7
你定义了一个实现 IObject 接口的参数和另一个实现 ITreeNode<IObject> 接口的参数,但我认为提问者需要一个实现这两个接口的单一参数。 - Tara McGrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接