在构造函数中传递派生对象

时间:2010-05-20 16:38:33

标签: c# .net vb.net inheritance polymorphism

这是一个令人费解的问题,希望我能说清楚。

我发现这可能是不可能的,但我试图看看是否有人有解决方案。

我有四个类,两个是核心类,两个是扩展的核心类:

extUser延长coreUser
extSecurity扩展coreSecurity

coreUser的构造函数中,你有这个:

public coreUser(string id, ref coreSecurity cs)

尝试扩展coreUser时,你会有这个:

public extUser(string id ref extSecurity es) : base(id, ref es)

这会失败,因为es的类型为extSecurity,基类期望类型为coreSecurity。我还没有找到这个以允许我在C#中覆盖这个基类。在VB中,它工作正常。

作为一个说明,我为了这个问题,100%无法对核心类进行更改。

想法?

3 个答案:

答案 0 :(得分:2)

这是因为ref参数的参数必须与完全的参数类型相同,而不仅仅是具有可用转换的参数。

你真的,真的需要ref部分吗?使构造函数采用ref参数非常不寻常。你确定这不仅仅是parameter passing mechanisms的混乱吗?我知道你已经说过你不能改变“核心”类型,但你至少应该考虑在未来的某个时候改变它们,除非他们真正使用这种“参考”功能。如果他们 使用“ref”,那么它是不合理的...... coreUser构造函数可能如下所示:

public coreUser(string id, ref coreSecurity cs)
{
    coreSecurity = new coreSecurity();
}

这会让你的extUser构造函数混淆,不是吗?然后es会引用一个不是extSecurity ...

的对象

(沿着类似的“那个奇怪的”行 - 你的类型真的是camelCased吗?.NET约定适用于PascalCased类型......)

如果确实只能更改extUser构造函数,那么正如Oded所说,您可以将参数类型更改为coreSecurity - 然后如果您需要将其更改为extSecurity {1}},你可以 施展它:

public extUser(string id, ref coreSecurity cs) : base(id, ref cs)
{
    extSecurity es = (extSecurity) cs;
    // Use es here
}

当然,如果cs在基础构造函数返回时引用的对象不是extSecurity,则会抛出异常...

答案 1 :(得分:0)

我建议您分析构造函数体内的代码,看看为什么需要coreSecurityextSecurity作为参考参数。

答案 2 :(得分:0)

ref用于操纵值类型(即引用,结构或整数等)。仅这一点就显示了构造函数的巨大误用(Constructor does real work,它是java,但也适用)。构造函数用于构造一个对象,您永远不需要ref参数。我知道这并没有真正回答你的问题,但你的代码存在严重缺陷。

ref关键字

一般来说,ref关键字允许通过引用传递参数。这意味着,对参数的更改将反映在方法范围之外。

示例1:传递ref int

public class Test
{
  public void TestMethod (ref int input)
  {
    input = 2;
  }
  public void Run()
  {
    int testVar = 1;
    TestMethod(ref testVar);
    //testVar is now 2
  }
}

示例2:传递参考字符串 通常,如果将字符串(或任何其他引用类型)传递给方法,则无法更改对象本身

public class Test
{
  public void TestMethod (ref string input)
  {
    input = "changed";
  }
  public void Run()
  {
    string testVar = "original";
    TestMethod(ref testVar);
    //testVar is now "changed"
  }
}

使用ref参数,它允许您更改对象本身,而不仅仅是其字段和属性。 referenceType上的ref参数允许您修改引用本身(通过为其指定新对象),而不仅仅是引用的内容(请参阅msdn)。