如何在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"
这样的事情可能发生吗?
由于两个子类都继承自超类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