c#中的多态性和关联关系
本文关键字:关联 关系 多态性 | 更新日期: 2023-09-27 17:53:17
我有类Foo和Bar实现接口IFooBar。我有另外两个类DerivedFoo和DerivedBar,他们继承了另一个类Base。IFooBar获得了一个使用Base作为参数的方法。
我希望Foo和Bar根据类型使用Base或DerivedFoo/DerivedBar。
给你一个更直观的例子(c#):
public abstract class Base : SuperBase
{
}
public class DerivedFoo : Base
{
public string FooProperty {get; set;}
}
public class DerivedBar : Base
{
public int FooProperty {get; set;}
}
public interface IFooBar
{
Base Update(Base toUpdate);
}
public class Foo : IFooBar
{
public Base Update(DerivedFoo toUpdate)
{
toUpdate.FooProperty = "X";
return toUpdate;
}
}
public class Bar: IFooBar
{
public Base Update(DerivedBar toUpdate)
{
toUpdate.BarProperty = 42;
return toUpdate;
}
}
这个实现失败了,正如你所期望的,因为我没有正确地实现接口。如果我正确地实现它(用Base类型替换DerivedFoo类型),我找不到我的属性FooProperty/BarProperty。你有什么技巧可以达到我所追求的行为吗?
编辑:实现Aleksey L.解决方案,我想要一个IFooBar列表,我使用ObservableCollection。
之前(在使用泛型之前),它在做(在另一个类中):
private ObservableCollection<IFooBar> m_foobarlist;
public ObservableCollection<IFooBar> FooBarList
{
get
{
return m_foobarlist;
}
set
{
m_foobarlist= value;
// other work
}
}
构造函数:
FooBarList = new ObservableCollection<IFooBar>
{
new Foo(),
new Bar()
};
我试着使用Aleksey提示后改变的类:
private ObservableCollection> m_foobarlist;
public ObservableCollection<IFooBar<Base>> FooBarList
{
get
{
return m_foobarlist;
}
set
{
m_foobarlist= value;
// other work
}
}
构造函数:
FooBarList = new ObservableCollection<IFooBar<Base>>
{
new Foo(),
new Bar()
};
但这似乎不起作用('Cannot convert Footo IFooBar' 'Cannot convert Bar to IFooBar')
使用泛型:
public interface IFooBar<T> where T : Base
{
T Update(T toUpdate);
}
public class Foo : IFooBar<DerivedFoo>
{
public DerivedFoo Update(DerivedFoo toUpdate)
{
toUpdate.FooProperty = "X";
return toUpdate;
}
}
public class Bar : IFooBar<DerivedBar>
{
public DerivedBar Update(DerivedBar toUpdate)
{
toUpdate.BarProperty = 42;
return toUpdate;
}
}
。不知道你想要实现什么,但是为了有一个IFooBar
的列表,你可以在这个接口上面定义一个基类:
public interface IFooBar
{
Base Update(Base toUpdate);
}
public abstract class BaseFooBar<T> : IFooBar where T : Base
{
protected abstract T UpdateDerived(T Base);
public Base Update(Base toUpdate)
{
var derived = toUpdate as T;
if (derived == null)
{
//not expected type. decide what you want to do in this case. throw exception?
}
return UpdateDerived(derived);
}
}
public class Foo : BaseFooBar<DerivedFoo>
{
protected override DerivedFoo UpdateDerived(DerivedFoo toUpdate)
{
...
Aleksey方法看起来不错,但我最终使用了这个技巧:
public class Foo : IFooBar
{
public Base Update(Base toUpdate)
{
var fooInstance = toUpdate as Foo;
if(fooInstance == null)
{
return null;
}
fooInstance.FooProperty = "X";
return fooInstance ;
}
}