我有一个抽象的基类,它从接口实现属性:
public abstract class AbstractItem : IPropertyListOwner
{
public ObservableCollection<IProperty> Properties { get; }
}
我的具体类现在还需要实现具体属性:
public class ConcreteItem : AbstractItem
{
public ObservableCollection<ConcreteProperty> Properties { get; }
}
我该如何实现?现在我看到以下方法:
- 只需使用单独的属性,不要从基类使用它
public class ConcreteItem : AbstractItem
{
public ObservableCollection<ConcreteProperty> ConcreteProperties { get; }
}
- 返回新的筛选可观察集合
public class ConcreteItem : AbstractItem
{
public ObservableCollection<ConcreteProperty> ConcreteProperties
{
get { return new ObservableCollection<ConcreteProperty>(base.Properties.OfType<ConcreteProperty>()); }
}
}
你会怎么做?有什么更好的方法吗?
泛
型将帮助您:
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>
执行某些操作,您还需要使用泛型的代码。
如果您发布用例,那么发布更明确的答案将有助于发布。
public abstract class AbstractItem<T> : IPropertyListOwner where T:IProperty
{
public ObservableCollection<T> Properties { get; private set; }
}
public class ConcreteItem : AbstractItem<ConcreteProperty>
{
}