繁体   English   中英

在使用抽象基 class 作为参数实现接口方法时访问派生的 class 属性

[英]Accessing derived class properties when implementing an interface method with abstract base class as parameter

我努力寻找这个问题的答案,所以如果它已经被问过,也许我的措辞是错误的。 我有一个抽象的基础 class 和一个派生的 class。

abstract class Foo
{
   protected int property1
   protected int property2
// etc..
}

我导出的 class 包含一些在基础 class 中找不到的额外属性:

class Fum : Foo
{
   public int UniqueProperty { get; set; }
}

现在我有一个接口,它带有一个采用抽象基 class 的方法:

interface IDoSomethingWithFoos
{
   void DoSomethingWithFoo(Foo fooey);
}

一个实现接口的 class

class FumLover : IDoSomethingWithFoos
{
   void DoSomethingWithFoo(Foo fooey)
   {
      // now in here i know i am going to be passed objects of Fum
      // and i want to access its unique properties

      fooey.UniqueProperty = 1;   // this doesn't work

      ((Fum)fooey).UniqueProperty = 1;   // this seems to work

      // as does..

      Fum refToFum = fooey as Fum;
      refToFum.UniqueProperty = 1;

   }
}

所以我的问题是:我是否以正确的方式处理这个问题? 尽管可以编译,但我没有足够的代码来确保它实际上可以正常工作。 我的另一个问题是:这是糟糕的设计吗? 有没有更好的办法?

*

再详细一点,因为自然的反应是,如果你要传递 Fum,那么让接口方法采用 Fum 而不是 Foo。

但是假设在我的 FumLover class 中,DoSomethingWithFoo 方法处理 95% 的属性是抽象低音 class 中的属性。 假设我有另一个名为 Fie 的派生 class,它有几个独特的属性。 现在假设我有一个 FieLover class,我想实现 DoSomethingWithFoo,因为我在这里要做的 95% 可以适用于所有 Foo,但同样,有一点 Fie 独有的。

什么是替代方案? 为每一个都有一个接口:IDoSomethingWithFums、IDoSomethingWithFies 等? 似乎我只是因为这 5% 的差异而失去了所有的抽象。

  // now in here i know i am going to be passed objects of Fum
  // and i want to access its unique properties

这是设计更改可能有所帮助的线索。 您当前的界面显示“我在Foo上工作”。 如果该实现仅适用于Fum ,那么您在说什么和在做什么不匹配。 如果您真的只期望Fum ,则将接口中的参数声明为Fum

如果您不想这样做,那么最好使用as语法,因为这样当有人认为他们可以传入Foo时,您不会抛出异常(因为嘿,界面他们可以。)

as代码应如下所示:

Fum fumObj = fooey as Fum;
if (fumObj != null)
    fumObj.UniqueProperty = 1;

更新

您对每个派生 class 的接口的建议实际上是可取的(因为他们说他们实际做了什么),但让我们退后一步:您实际上想在这里完成什么? 如果您希望IDoSomethingWithFoos利用Foo作为基础 class 的位置(尽管是抽象的),那么您需要确保调用DoSomethingWithFoo对所有Foo都有意义。 如果不是,那你已经输了,因为即使你声称自己是一个 FooLover,你真的只爱Fum s(或Fie s。)

一种解决方案是在Foo本身上声明一个abstract DoSomething()方法。 现在,你可以有一个List<Foo> ,并且有这样的代码:

foreach (Foo foo in fooList)
    foo.DoSomething();

现在您实际上正在利用抽象。 你不在乎那些是什么类型的Foo :它们都做一些事情,可能基于仅派生的 class 独有的属性(不需要强制转换。)

我认为你所做的很好,因为 Fum 扩展了 Foo 你应该能够以你的方式投射它。

另一种方法是实现 IFoo 接口并将其传递给方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM