2

我有一个从接口实现属性的抽象基类:

public abstract class AbstractItem : IPropertyListOwner
{
    public ObservableCollection<IProperty> Properties { get; }
}

我的具体类现在还需要实现具体属性:

public class ConcreteItem : AbstractItem
{
    public ObservableCollection<ConcreteProperty> Properties { get; }
}

我该如何做到这一点?现在我看到以下方法:

  1. 只需使用单独的属性,不要使用基类中的属性
public class ConcreteItem : AbstractItem
{
    public ObservableCollection<ConcreteProperty> ConcreteProperties { get; }
}
  1. 返回一个新的过滤 ObservableCollection
public class ConcreteItem : AbstractItem
{
    public ObservableCollection<ConcreteProperty> ConcreteProperties
    {
        get { return new ObservableCollection<ConcreteProperty>(base.Properties.OfType<ConcreteProperty>()); }
    }
}

你会怎么做?有更好的方法吗?

4

2 回答 2

3

泛型将帮助您:

interface IPropertyListOwner<T>
  where T : IProperty
{
    ObservableCollection<T> Properties { get; }
}

abstract class AbstractItem<T> : IPropertyListOwner<T>
  where T : IProperty
{
    public abstract ObservableCollection<T> Properties { get; }
}

class ConcreteProperty : IProperty { }

class ConcreteItem : AbstractItem<ConcreteProperty>
{
    public override ObservableCollection<ConcreteProperty> Properties 
    { 
        get
        {
            // ...
        }
    }
}

但是,如果您打算在某个地方使用IPropertyListOwner.

假设,你有一些代码,应该只适用于IProperty. 例如,让这段代码显示属性的名称:

interface IProperty
{
    string Name { get; }
}

在泛型的情况下,你不能编写foreach,它将遍历属性集合,而不知道T在运行时:

void WritePropertyNames<T>(IPropertyListOwner<T> owner)
{
    foreach (var property in owner.Properties)
    {
        Console.WriteLine(property.Name);
    }
}

换句话说,要使用泛型做某事,IPropertyListOwner<T>您也需要使用泛型的代码。

如果您要发布用例,这将有助于发布更清晰的答案。

于 2013-09-18T07:54:04.203 回答
2
public abstract class AbstractItem<T> : IPropertyListOwner where T:IProperty
{
    public ObservableCollection<T> Properties { get; private set; }
}

public class ConcreteItem : AbstractItem<ConcreteProperty>
{

}
于 2013-09-18T07:53:35.763 回答