如何在C#中创建指向对象的指针?

时间:2016-08-03 23:10:14

标签: c#

我对C#很新,但我在C中做了大量的编程。

我有一个包含两级类的库,其中Level 2继承了Level 1的属性,如下所示。

public class Level1
{
    int a;
    int b;
    string c;
}
// inherits from Level1
public class Level2a : Level1
{
    string d;
    bool e;
}
public class Level2b : Level1
{
    int f;
    bool g;
}

我想要的是创建一个基本上可以"指向"基于switch案例的Level2a或Level2b实例化对象。

Level2a myObjectA = new Level2a();
Level2b myObjectB = new Level2b();

myObjectA.c = "This is ";        // c is inherited from Level1
myObjectA.d = "my string";
bool myVariable = 0;
var myGeneric;     // not sure how to declare this

switch(myVariable) {
    case 0: myGeneric = myObjectA; break; // not sure how to assign this
    case 1: myGeneric = myObjectB; break;
    default: break;
}

// Then I should be able to do this:
Console.WriteLine(myGeneric.c + myGeneric.d);
// Console prints out "This is my string"

这样的事情可能吗?

5 个答案:

答案 0 :(得分:1)

您可以创建Level1类型的变量:

Level2a myObjectA = new Level2a();
Level2b myObjectB = new Level2b();

...

Level1 myGeneric = myObjectA;  // Assigning more derived object to less derived variable

应该注意,这不起作用:

Console.WriteLine(myGeneric.c + myGeneric.d);

由于Level1没有d成员,您将收到编译错误。如果需要,可以将它强制转换为更多派生类型,但那时你就违反了OOP原则:

Console.WriteLine(myGeneric.c + ((Level2a)myGeneric).d);

答案 1 :(得分:1)

您想要实现多态性。您需要通过继承的类来创建新对象,然后将它们分配给基类中的变量。像这样。

Level1 myObjectA = new Level2a();
Level1 myObjectB = new Level2b();

myObjectA.a = 1;
myObjectB.a =2;

您甚至可以将它们添加到List并调用已在基类中注册的方法。

默认情况下,C#使用指针,因此它会自动使用覆盖方法(如果有的话)。 我改变你的代码

修改 显然我的代码不够明确。看看下面的代码

public class Level1
{
   public int a;
  public  int b;
    public string c;

    public virtual string GetString()
    {
      return c;
    }

}
// inherits from Level1
public class Level2a : Level1
{
   public string d;
   public bool e;
    public override string GetString()
    {
      return base.GetString() + d ;
    }    
}
public class Level2b : Level1
{
   public int f;
   public bool g;

}
Level1 obj= new Level2a();
 ....
Console.WriteLine(obj.GetString());
 // This is my string
obj= new Level2b();
.....
Console.WriteLine(obj.GetString());
// This is

答案 2 :(得分:1)

回答你的确切问题是dynamic,这会将所有类型检查延迟到运行时并让你的编译和运行代码成功:

dynamic myGeneric = null;  

注意:这通常不是C#的方式,并且代码的某些重构(可能为两个类创建接口)可能会为您提供强类型代码。

答案 3 :(得分:1)

如上所述,您需要接口 - 以及一些有趣的显式实现和强制转换。 C#不支持多重继承类,但您可以在类中包含多个接口的行为。

using System;

namespace tests
{
    public interface ILevel1
    {
        int a { get; set; }
        int b { get; set; }
        string c { get; set; }
    }

    public interface ILevel2a
    {
        string d { get; set; }
        int e { get; set; }
    }

    public interface ILevel2b
    {
        int f { get; set; }
        bool g { get; set; }
    }

    public class Level2a : ILevel1, ILevel2a {
        int ILevel1.a { get; set; }
        int ILevel1.b { get; set; }
        string ILevel1.c { get; set; }

        string ILevel2a.d { get; set; }
        int ILevel2a.e { get; set; }
    }

    public class Level2b : ILevel1, ILevel2b
    {
        int ILevel1.a { get; set; }
        int ILevel1.b { get; set; }
        string ILevel1.c { get; set; }

        int ILevel2b.f { get; set; }
        bool ILevel2b.g { get; set; }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Level2a myObjectA = new Level2a();
            Level2b myObjectB = new Level2b();

            ((ILevel1)myObjectA).c = "This is ";
            ((ILevel2a)myObjectA).d = "my string";

            ((ILevel1)myObjectB).c = "Hey, I'm a Level2b!";

            int myVariable = 0;

            dynamic myObject = null; // declare as dynamic

            switch (myVariable)
            {
            case 0: myObject = myObjectA; break;
            case 1: myObject = myObjectB; break;
            default:
                break;
            }

            if (myObject is Level2a)
            {
                Console.WriteLine(((ILevel1)myObject).c + ((ILevel2a)myObject).d);
            }
            else if (myObject is Level2b)
            {
                Console.WriteLine(((ILevel1)myObject).c);
            }

            Console.ReadKey();
        }
    }
}

答案 4 :(得分:0)

由于两个子类都继承自超类Level1,因此您可以执行以下操作:

Level2a myObjectA = new Level2a();
Level2b myObjectB = new Level2b();

Level1 myObjectIReallyLike;
switch(myVariable) {
    case 0:
        myObjectIReallyLike = myObjectA;
        break;
    case 2:
        myObjectIReallyLike = myObjectB;
        break;
 }

如果你将它用于游戏(统一,哭引擎?),你可能想要定义一个通用界面,而不是直到继承,直到你达到500级。