【问题标题】:Specifying multiple interfaces for a parameter为参数指定多个接口
【发布时间】:2011-05-03 16:09:12
【问题描述】:

我有一个实现两个接口的对象...接口是:

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
}

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

【问题讨论】:

标签: c# interface composition


【解决方案1】:
public void Foo<T>(T myParam)
    where T : IObject, ITreeNode<IObject>
{
    // whatever
}

【讨论】:

  • 这是一个很好的答案。我意识到我遗漏了一些重要的信息。我指的函数是另一个类的构造函数(场景是一个节点构建另一个节点)可以在构造函数中使用泛型
  • 由于这个答案对我的问题有效,我会接受它,但构造函数的事情让我很头疼:)
  • 在这种情况下,我认为您必须使该类通用。看起来你不能在非泛型类上使用泛型构造函数。
  • 方法的好解决方案。不幸的是,如果不使所有类通用,就很难将此解决方案应用于属性。
  • @AgostinoX 确实如此。属性的值必须具有单一类型。您可以选择一个接口作为属性类型,并让 setter 验证该值是否也实现了另一个接口,但 getter 无法说它总是返回实现两个接口的值。 (这就是代码合同的好处。)
【解决方案2】:

在 C# 中,接口本身可以继承自一个或多个其他接口。因此,一种解决方案是定义一个接口,例如派生自IObjectITreeNode&lt;T&gt;IObjectTreeNode&lt;T&gt;

【讨论】:

  • -1:这会改变要求。此方法不需要参数来实现 IObject 和 ITreeNode,它需要参数来实现 IObjectTreeNode。因此,不允许实现两个接口但不实现组合的对象,而它们应该实现。
【解决方案3】:

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

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

如果您不希望经常使用上述接口,另一种选择是使有问题的方法/函数具有通用性。

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

【讨论】:

【解决方案4】:
public  void MethodName<TParam1, TParam2>(TParam1 param1, TParam2 param2) 
    where TParam1 : IObject
    where TParam2 : ITreeNode<IObject> 

【讨论】:

  • 您已经定义了一个实现IObject 的参数和另一个实现ITreeNode&lt;IObject&gt; 的参数,但我认为提问者需要一个实现这两者的单个参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-22
  • 1970-01-01
相关资源
最近更新 更多