【问题标题】:Is there a way to use a property with same name but is of different type in derived class?有没有办法在派生类中使用具有相同名称但类型不同的属性?
【发布时间】:2013-06-11 23:59:35
【问题描述】:

我有使用 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();
}

【问题讨论】:

  • 对于 VB 程序员,在为属性、字段等创建新定义时使用关键字“阴影”。如果返回值不匹配,这可能会影响您在转换为父类型时的动态编程.

标签: c# .net


【解决方案1】:

您可以像这样使用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 更喜欢显式接口而不是隐藏基的含义
猜你喜欢
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多