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')

c#中的多态性和关联关系

使用泛型:

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 ;
   }
}