[英]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.