抽象属性帮助

时间:2011-05-14 02:18:35

标签: c#

这是你如何得到我的抽象类属性?

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

3 个答案:

答案 0 :(得分:5)

因为myProperty被声明为public,所以你可以使用它,就好像它在派生类中是本地的一样,你不需要转换为基类类型。

如果您在基类中将其声明为virtual并在派生类中重写它,那么您需要进行强制转换,那么如果要调用基本版本,则需要显式。

基类是否正在实现接口并且派生类想要调用该版本并不重要 - 它仍然被声明为public(protected也可以工作),并且没有覆盖取代它。

答案 1 :(得分:1)

假设,在您的示例中,myobjIMyObj的实例,您确实需要投射myobj才能引用myProperty。这是因为IMyObj的实例对类MyObjBaseMyObj的成员一无所知。虽然这有点奇怪,但可能表示设计错误,因为想要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.myPropertyasDerived.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";         
}