比较列表中的类型

时间:2014-05-11 09:19:49

标签: c# types unity3d

我在Unity3D Q& A上问了一个类似的问题,但我没有得到回应。我终于回到了这个项目,仍然有同样的问题。

Link To Unity Question

我已经搜索过,但我认为我没有找到合适的关键字,因为我仍然没有找到合适的答案。无论如何,我会以不同的方式提出问题,希望有人能指出我正确的方向。

以下是我提出的代码,它不是游戏中的实际代码,但它在显示我的问题方面做得很好。

基本上,在build()方法中,我想检查两个列表是否都包含相同类型的工具,而不是实际硬编码类型。我并不关心特定的工具实例,只是它属于某种类型。目的是我可以创建新工具,而无需修改构建方法以合并这些新类型。

如果有更好的方法可以做到这一点我全都耳朵。

由于

namespace TypeExample
{
    class Tool
    {

    }

    class Spanner : Tool
    {

    }

    class Wrench : Tool
    {

    }

    class Builder
    {
        List<Tool> toolsAvailable = new List<Tool>();

        List<Tool> toolsRequired = new List<Tool>();

        public Builder()
        {
            Spanner spanner = new Spanner();
            Wrench wrench = new Wrench();

            toolsRequired.Add(spanner);
            toolsRequired.Add(wrench);
        }

        public void GiveTool(Tool tool)
        {
            toolsAvailable.Add(tool);
        }

        public void build()
        {
            // if true

            Console.WriteLine("Building");

            // else

            Console.WriteLine("I don't have the tools to build!");

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Spanner spanner = new Spanner();
            Wrench wrench = new Wrench();

            Builder builder = new Builder();

            builder.GiveTool(spanner);
            builder.GiveTool(wrench);

            builder.build();

            Console.ReadLine();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

基本上你应该使用Linq从集合中获取所有类型,然后计算结果。

var toolsAvailableTypes = toolsAvailable.Select(t => t.GetType()).Distinct();
var toolsRequiredTypes = toolsRequired.Select(t => t.GetType()).Distinct();
if (toolsRequiredTypes.Except(toolsAvailableTypes).Any())
{
    //building
}

目前尚不清楚,您是否应该只兼容各种类型的工具或数量。我的回答是假设您不关心数量,当您需要两个时,您可以使用一个spanner进行构建。

<强> -Update

为了符合关于子类的要求(Sriram Sakthivel提到它),您可以检查可用工具类型是否是所需工具类型的子类,以便在需要SpecialSpanner时可以使用任何Spanner

var toolsAvailableTypes = toolsAvailable.Select(t => t.GetType()).Distinct().ToList();
var toolsRequiredTypes = toolsRequired.Select(t => t.GetType()).Distinct().ToList();

if (CanBuild(toolsAvailableTypes, toolsRequiredTypes))
{
    Console.WriteLine("building");
}
else
{
    Console.WriteLine("not enough minerals");
}

CanBuild方法:

bool CanBuild(List<Type> toolsAvailableTypes, List<Type> toolsRequiredTypes)
{
    foreach (var requiredType in toolsRequiredTypes)
    {
        bool isAvailable = toolsAvailableTypes.Any(availableType => availableType.IsSubclassOf(requiredType) || availableType == requiredType);
        if (!isAvailable)
        {
            return false;
        }
    }
    return true;
}

答案 1 :(得分:1)

var reqdTypes = toolsRequired.Select(x => x.GetType());
var availableTypes = toolsAvailable.Select(x => x.GetType());

if (reqdTypes.Except(availableTypes).Any())
{
    //Something exist in reqdTypes which is not in availableTypes
}

注意:如果您提供的衍生类型多于预期类型,则会失败。例如,如果您提供SpecialSpannerSpanner,则无效。