我对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"
这样的事情可能吗?
答案 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级。