c#是一个接受所有类型的列表或数组

本文关键字:类型 列表 数组 一个 | 更新日期: 2023-09-27 17:50:18

我正在考虑在XNA 3.1中创建一个处理阴影绘制的类。我知道有很多方法可以做到这一点,但我想做一些类似于所有应该有阴影的对象的列表,并将该列表传递给阴影类,以便它遍历每个对象并绘制阴影。

我想这样做的原因是我可以很容易地控制阴影是否存在,只需一个布尔值

所有类型的List可能不太可能,我的备份是Object类型的List,但我不知道如何将Object类型的List中的元素转换回各自的类型,以便我可以访问它们的属性。

我的第二个备份是使所有将有阴影的对象派生自一个叫做ShadowObject之类的类,并使该类型的列表。这是一个非常简单的解决方案,但我还没有这样做的原因是,我不喜欢一个虚拟类的想法,只是让一些工作,但也许我应该开始喜欢它。

我最后的备份是进入每个有阴影的类,并有一个布尔值来查看是否应该绘制阴影并处理类本身的绘图,我认为这甚至不应该被视为一个选项,因为如果我想改变阴影机制,我必须在每个类中改变它。

所以我想所有类型的列表是我对公众的正式问题,但我对我的后备计划的答案,建议和批评持开放态度。

编辑:我知道界面,但我的回应是在xixonia的回答的评论中,在阅读了更多关于界面的内容后,我认为有一个暗影施法者职业会更合适。它可以处理所有的阴影绘制,因为所有的阴影都是以相同的方式绘制的,我不需要像界面那样为每个对象单独定义它。

c#是一个接受所有类型的列表或数组

我认为你应该使用一个接口,并确保你所有的"DrawShadow"方法匹配该接口。这样你就可以创建一个与接口匹配的阴影施法者列表。

只要一个对象实现了那个接口,你就知道你可以告诉它画一个阴影。如果使用正确的绘制工具,则阴影的实际绘制将留给对象本身。

例如:

class Program
{
    public static void Main()
    {
        var shadowCasters = new List<ICastShadow>();
        shadowCasters.Add(new Car());
        shadowCasters.Add(new Plane());
        var castShadows = true;
        if (castShadows)
        {
            foreach (var caster in shadowCasters)
            {
                caster.DrawShadow(null); 
            }
        }
        Console.Read();
    }
    public class Car : ICastShadow
    {
        public void DrawShadow(object device)
        {
            Console.WriteLine("Car Shadow!");
        }
    }
    public class Plane : ICastShadow
    {
        public void DrawShadow(object device)
        {
            Console.WriteLine("Plane Shadow!");
        }
    }
    public interface IShadowCaster
    {
        void DrawShadow(object device);
    }
}

当你需要测试你的对象是否能够投射阴影时,你可以使用"is"关键字…

if(myTrain is ICastShadow)
{
    shadowCasters.Add(myTrain);
}

希望这对你有帮助!:)

编辑:

你不想使用继承的原因是,如果你的游戏对象都以不同的方式绘制阴影,如果你的一些派生类不投射阴影。例如:

你有一个砖建筑和一个玻璃建筑。砖房应投阴影,玻璃房不应投阴影。它们都继承了建筑,而建筑继承了暗影施法者。即使你所有的影子投射类都以同样的方式绘制阴影,你仍然需要使ShadowCaster的方法成为虚拟的,这样GlassBuilding就可以覆盖它们,当方法被调用时什么也不做。

使用组合而不是继承(即:使用接口),您将能够在上仅在那些实际投射阴影的类上组合阴影绘制方法,并且您在层次结构中少了一个类(这使得可维护性变得轻而易举)。

那么,当你使用一个接口时,你开始一遍又一遍地重复相同的逻辑,因为你的阴影绘制类都以同样的方式绘制阴影,会发生什么呢?显然这不是一个好主意。但如果它们都以相同的方式绘制阴影,你可以使用另一个类为它们绘制阴影。然后是"暗影施法者"职业。

每个对象上的阴影绘制实现将调用ShadowCaster上的一个方法来为它绘制阴影。这允许每个对象以不同的方式绘制阴影的选项,但也为每个对象提供了使用默认阴影绘制实现的方法。它还提供了一种方法,可以轻松地添加和删除为特定对象绘制阴影的能力(简单地不要让对象实现ICastShadow接口)。

更进一步,你可以像对待另一种绘画方法一样对待阴影投射,并创建一个通用的界面来绘制阴影/粒子/反射/发光等,并创建不同的"模块"来做这些不同的事情。而不是让你的类实现"ICastShadows",让它实现"IDrawModules",然后在运行时给每个类正确的模块。

换句话说,你可以添加一个"CastShadow"模块到BrickBuilding,并添加一个"反射"模块到GlassBuilding,并有你的代码调用"DrawModules"两个对象(从IDrawModules接口)。

好了,这真是太长了,希望这能帮到你,而且不会让你太困惑。

我建议阅读头优先设计模式的前两章。这是一本基于java的书,但其原理适用于大多数语言。

与其创建一个"虚拟类" ShadowObject,不如直接创建一个接口IShadowObject来公开所有必要的方法,并使用:

List<IShadowObject>

我不太了解游戏开发,但看起来System.Generic.Collection.List是由XNA框架支持的。这是任何类型的列表。

可以使用"is"运算符检查类型

public bool check(object obj)
{
   return obj is ShadowStuff;
   // or obj.GetType() == ShadowStuff
}

转换:

(ShawdowStuff) obj  ;