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

本文关键字:对象 指针 创建 | 更新日期: 2023-09-27 18:00:10

我对C#还很陌生,但我已经用C.做了相当多的编程

我有一个库,里面有两个级别的类,其中级别2继承级别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;
}

我想要的是创建一个通用对象,它基本上可以"指向"基于开关情况的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"

这样的事情可能发生吗?

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

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

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

如果你在游戏中使用这个(团结,哭泣引擎?),你可能想定义一个通用接口,而不是向上继承,直到达到500级。

您可以创建类型为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);

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

dynamic myGeneric = null;  

注意:这通常不是C#的方法,对代码进行一些重构(可能为两个类制作接口)可能会给您提供强类型代码。

正如前面提到的,您需要接口——以及一些有趣的显式实现和强制转换。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();
        }
    }
}
您想要实现多态性。您需要通过继承的类来创建对象,然后将它们分配给基类中的变量。像这样。
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