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

时间:2016-06-30 11:33:50

标签: c# inheritance interface polymorphism

我有类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&gt; 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()
            };

但这似乎不起作用('无法转换Footo IFooBar''无法将Bar转换为IFooBar')

2 个答案:

答案 0 :(得分:3)

使用generics

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)
    {
...

答案 1 :(得分:0)

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