这是你如何得到我的抽象类属性?
public interface IMyObj(
void myMethod();
)
public abstract class MyObjBase
(
public string myProperty{get; set;}
)
public class myObj : MyObjBase, IMyObj
(
)
public void SomeMethod(IMyObj myobj)
{
// is there another way to do this, seems awkward
(myobj as myobjBase).myProperty = "value";
}
答案 0 :(得分:5)
因为myProperty
被声明为public,所以你可以使用它,就好像它在派生类中是本地的一样,你不需要转换为基类类型。
如果您在基类中将其声明为virtual
并在派生类中重写它,那么您需要进行强制转换,那么如果要调用基本版本,则需要显式。
基类是否正在实现接口并且派生类想要调用该版本并不重要 - 它仍然被声明为public(protected
也可以工作),并且没有覆盖取代它。
答案 1 :(得分:1)
假设,在您的示例中,myobj
是IMyObj
的实例,您确实需要投射myobj
才能引用myProperty
。这是因为IMyObj
的实例对类MyObjBase
或MyObj
的成员一无所知。虽然这有点奇怪,但可能表示设计错误,因为想要IMyObj
接口的代码实际上不应该知道对象实例的类型是什么。如果你想从myProperty
的实例获得IMyObj
,那么这是一个非常好的迹象,表明该属性需要在接口本身中定义。
但是,为了理解类型转换在您的示例中如何工作,请注意您可以转换为基类或派生类:
MyObjBase asBase = myobj as MyObjBase;
MyObj asDerived = myobj as MyObj;
asBase.myProperty = "Hello ";
asDerived.myProperty = "World"; // refers to the same property as previous line
如果你连接最后两个,你会得到:
string x = asBase.myProperty + asDerived.myProperty; // x = "WorldWorld"
现在,假设您有一对虚拟/覆盖属性定义,如下所示:
public virtual string myProperty { get; set; } // in MyObjBase
public override string myProperty { get; set; } // in MyObj
然后,asBase.myProperty
和asDerived.myProperty
仍引用相同的属性,但现在它是派生类的myProperty
。实际上,给定实例myobj
,无法获得基类的myProperty
(通过反射除外)。此外,给定myobj
,基类内的代码本身将不再引用其自己的myProperty
。唯一可以获取基类属性的代码是派生类中的某个方法(或构造函数)。
例如:
class MyObjBase
{
public virtual string myProperty { get; set; }
public void Foo()
{
myProperty = "something"; // refers to derived class property, if
// it overrides myProperty
}
...
}
class MyObj: MyObjBase, IMyObj
{
public override string myProperty { get; set; }
public string Bar()
{
base.myProperty = "Hello ";
myProperty = "World";
return base.myProperty + myProperty; // returns "Hello World"
}
...
}
答案 2 :(得分:1)
如果要访问接口和抽象类成员,则参数的类型必须是“myObj”类型(因为类实现了接口和抽象类)。你的intellisense正确地告诉你,如果你传入一个接口,它需要任何实现该接口的派生类,但无法确定你正在实现的其他抽象类或接口。我建议:
public interface IMyObj
{
void myMethod();
}
public abstract class MyObjBase
{
public string myProperty { get; set; }
}
public class myObj : MyObjBase,IMyObj
{
public void myMethod()
{ }
}
public void SomeMethod(myObj myobj)
{
myobj.myProperty = "value";
}