接口和泛型类约束之间的循环关系



我似乎对此处于一个思维循环中。我不能在INameManageable中使用对父名称管理器的引用(其对象归NameManager所有(,因为它是通用的。

另一方面,如果我使INameManageable本身成为一个通用接口(即INameManageable(,我可以在其中使用对NameManager的引用。但是,我无法再从同一个INameManageable中派生出我所有的可命名类。

public interface INameManageable
{
    NameManager getParent(); // doesn't work because NameManager is generic!
    setParent(NameManager newParent);
    string getName(); // not relevant for the problem
    void setName(string name);
}
public class NameManager<T> where T: INameManageable
{
    readonly List<T> namedItems = new List<T>();
    public T Add(T item)
    {
        item.setParent(this);
        // ...
    }
    // ...
}
public class X: INameManageable
{
    // ...
}
public class Y: INameManageable
{
    // ...
}
public class ABunchOfNameManagers
{
    NameManager<X> anXNameManager;
    NameManager<Y> aYNameManager;
}

在这种情况下,如何建立对父级的引用?我可能会面对自己,一旦我知道怎么做......

现在我明白了!这基本上是@JDDavis在他的(删除的(答案中建议的。谢谢,伙计,我希望我能再次为此投票给你!很抱歉没有看到潜力。

关键是使接口也通用。

public interface INameManageable<T>
{
    NameManager<T> getParent();
    string getName();
    // derived class should use explicit interface implementation
    // so that no-one from external can fiddle with name or parent
    setParent(NameManager<T> newParent);
    void setName(string name);
}
public class NameManager<T> where T: class, INameManageable<T>
{
    readonly List<T> namedItems = new List<T>();
    public T Add(T item)
    {
        // ...
        namedItems.Add(item);
        item.setParent(this);
    }
}
public class X: INameManageable<X>
{
    // publicly accessible
    public NameManager<T> getParent() {/* ... */}
    public string getName() {/* ... */}
    // this is called "explicit interface implementation";
    // basically means "private", unless somebody explicitly
    // casts us to the interface (so it's at least discouraged)
    void INameManageable<T>.setName(string name) {/* ... */}
    void INameManageable<T>.setParent(NameManager<T> nameManager) {/* ... */}
}
public class Y: INameManageable<Y>
{
    // ... same here ...
}
public class ABunchOfNameManagers
{
    NameManager<X> anXNameManager;
    NameManager<Y> aYNameManager;
}

感谢大家富有成效的讨论!

编辑:我忘了同步我在此期间所做的更改。我怀疑这就是导致@Servy对类型安全的批评的原因。无论如何,它对我的应用程序工作正常。

相关内容

  • 没有找到相关文章

最新更新