Lee*_*Lee 6 c# overloading class-hierarchy
问题
我试图避免代码如下所示:
If(object Is Man)
Return Image("Man")
ElseIf(object Is Woman)
Return Image("Woman")
Else
Return Image("Unknown Object")
Run Code Online (Sandbox Code Playgroud)
我认为我可以通过方法重载来实现这一点,但它总是选择最少的派生类型,我认为这是因为重载是在编译时确定的(与重写不同),因此只能在以下代码中假设基类:
代码结构:
NS:Real
RealWorld (Contains a collection of all the RealObjects)
RealObject
Person
Man
Woman
NS:Virtual
VirtualWorld (Holds a reference to the RealWorld, and is responsible for rendering)
Image (The actual representation of the RealWorldObject, could also be a mesh..)
ArtManager (Decides how an object is to be represented)
Run Code Online (Sandbox Code Playgroud)
代码实现(关键类):
class VirtualWorld
{
private RealWorld _world;
public VirtualWorld(RealWorld world)
{
_world = world;
}
public void Render()
{
foreach (RealObject o in _world.Objects)
{
Image img = ArtManager.GetImageForObject(o);
img.Render();
}
}
}
static class ArtManager
{
public static Image GetImageForObject(RealObject obj)// This is always used
{
Image img = new Image("Unknown object");
return img;
}
public static Image GetImageForObject(Man man)
{
if(man.Age < 18)
return new Image("Image of Boy");
else
return new Image("Image of Man");
}
public static Image GetImageForObject(Woman woman)
{
if (woman.Age < 70)
return new Image("Image of Woman");
else
return new Image("Image of Granny");
}
}
Run Code Online (Sandbox Code Playgroud)
我的场景: 基本上我正在创建一个游戏,并希望将现实世界的类(例如男人)与屏幕上的类(一个人的图像)分离.现实世界的对象应该不知道它的屏幕表示,表示将需要知道真实的对象(知道这个人有多大,因此绘制了多少皱纹).我希望有一个后备,如果一个RealObject是一个未知的类型,它仍然显示一些东西(如一个大红十字).
请注意,此代码不是我正在使用的,它是一个简化版本,以保持问题清晰.如果适用,我可能需要稍后添加详细信息,我希望此代码的解决方案也可以在应用程序中使用.
解决这个问题最优雅的方法是什么? - 没有RealObject本身保存有关如何表示它的信息.XNA游戏是一个非常重的AI概念证明,如果它证明是可行的,将从2D改为3D(可能支持低端计算机).
使用工厂:
public class ImageFactory
{
Dictionary<Type, Func<IPerson, Image>> _creators;
void Assign<TPerson>(Func<IPerson, Image> imageCreator) where T : IPerson
{
_creators.Add(typeof(TPerson), imageCreator);
}
void Create(Person person)
{
Func<IPerson, Image> creator;
if (!_creators.TryGetValue(person.GetType(), out creator))
return null;
return creator(person);
}
}
Run Code Online (Sandbox Code Playgroud)
分配工厂方法:
imageFactory.Assign<Man>(person => new Image("Man");
imageFactory.Assign<Woman>(person => new Image("Big bad mommy");
imageFactory.Assign<Mice>(person => new Image("Tiny little mouse");
Run Code Online (Sandbox Code Playgroud)
并使用它:
var imageOfSomeone = imageFactory.Create(man);
var imageOfSomeone2 = imageFactory.Create(woman);
var imageOfSomeone3 = imageFactory.Create(mice);
Run Code Online (Sandbox Code Playgroud)
为了能够为男性返回不同的图像,您可以使用一个条件:
factory.Assign<Man>(person => person.Age > 10 ? new Image("Man") : new Image("Boy"));
Run Code Online (Sandbox Code Playgroud)
为了清楚起见,您可以将所有更复杂的方法添加到类中:
public static class PersonImageBuilders
{
public static Image CreateMen(IPerson person)
{
if (person.Age > 60)
return new Image("Old and gready!");
else
return new Image("Young and foolish!");
}
}
Run Code Online (Sandbox Code Playgroud)
并分配方法
imageFactory.Assign<Man>(PersonImageBuilders.CreateMen);
Run Code Online (Sandbox Code Playgroud)