2013-06-11 101 views
12

我有使用BaseClass的遗留代码,代码期望customerid的类型为int。然后我需要创建一个新的类DerivedClass,它的行为非常像BaseClass,但现在customerid需要是一个字符串。遗留代码无法修改,因此无需进行测试。有没有办法在派生类中使用具有相同名称但属于不同类型的属性?

如何使用继承(或任何其他方式)获得我想要的效果?

下面的Linqpad测试代码说明了我需要做的事情。显然它不会编译,因为DerivedClass中的customerid需要是int。我需要一个名为customerid的字符串属性。它需要是该名称,因为其他代码将使用此类而不是BaseClass,并且期望相同的命名属性为字符串类型。

public class BaseClass 
{ 
    public virtual int customerid {get; set;} 

    public void printname() 
    { 
     customerid = 1; 
     customerid.Dump(); 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public override string customerid {get; set;} 

    public void PrintCustomerID() 
    { 
     customerid = "jshwedeX"; 
     customerid.Dump(); 
    } 
} 



void Main() 
{ 
    DerivedClass dc = new DerivedClass(); 
    dc.printname(); 
} 
+3

你可以使用[显式接口实现](http://msdn.microsoft.com/en-us/library/vstudio/ms173157.aspx)? – millimoose

+0

对于VB程序员,在为属性,字段等创建新定义时使用关键字'Shadows'。如果返回值不匹配,则可能会在投射到父类型时影响您的动态编程。 – ps2goat

回答

21

可以使用new修改如下:

public class BaseClass 
{ 
    public virtual int customerid {get; set;} 

    public void printname() 
    { 
     customerid = 1; 
     customerid.Dump(); 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public new string customerid {get; set;} 

    public void PrintCustomerID() 
    { 
     customerid = "jshwedeX"; 
     customerid.Dump(); 
    } 
} 

这会给你想要的结果,但它也将隐藏在基类中的属性。如果您将DerivedClass的实例作为BaseClass变量引用,则只能引用基类上的属性;不是派生类。

换句话说:

BaseClass instance = new DerivedClass(); 
string customerId = instance.customerid; // <- this won't compile 

另一种方法是使用显式接口实现:

public interface IBase 
{ 
    int customerid { get; set; } 
} 

public interface IDerived 
{ 
    string customerid { get; set; } 
} 

public class Derived : IBase, IDerived 
{ 
    int IBase.customerid { get; set; } 
    string IDerived.customerid { get; set; } 
} 

当你的Derived实例存储在IBase类型的变量,customerid将解析int版本,并且当它存储在类型为IDerived的变量中时,它将解析为string版本:

var derived = new Derived(); 
IBase ibase = derived; 
IDerived iderived = derived; 
int id1 = ibase.customerid; // <- compiles just fine 
string id2 = iderived.customerid; // <- compiles just fine 

您还可以使用铸造:

var instance = new Derived(); 
int id1 = ((IBase)instance).customerid; 
string id2 = ((IDerived)instance).customerid; 

记住显式接口实现引起除非该变量是接口类型的实现成员不可见:

var instance = new Derived(); 
var customerid = instance.customerid; // <- this won't compile 
+1

+1更喜欢显式接口来隐藏基的含义 –

相关问题