简体   繁体   English

比较列表中的类型

[英]Comparing types in lists

I asked a similar question to this over on Unity3D Q&A, but I didn't get a response. 我在Unity3D Q&A问了一个类似的问题,但我没有得到回复。 I've finally got back round to this project and still have the same issue. 我终于回到了这个项目,仍然有同样的问题。

Link To Unity Question 链接到团结问题

I have searched, but I don't think I've hit the right keywords cause I still haven't found an answer that fits. 我搜索过,但我认为我没有找到合适的关键字,因为我还没有找到合适的答案。 Anyway, I will ask the question a different way and hopefully someone can point me in the right direction. 无论如何,我会以不同的方式提出问题,希望有人可以指出我正确的方向。

So below is the code that I have come up with, it's not the actual code in the game, but it does a good job at showing my problem. 所以下面是我提出的代码,它不是游戏中的实际代码,但它在显示我的问题方面做得很好。

Basically, in the build() method I want to check that both lists each contain the same type of tool, without actually hard coding the type. 基本上,在build()方法中,我想检查两个列表是否都包含相同类型的工具,而不是实际硬编码类型。 I don't care about the specific tool instance, just that it is of a certain type. 我不关心特定的工具实例,只是它是某种类型。 The aim is that I can create new tools without having to modify the build method to incorporate these new types. 目的是我可以创建新工具,而无需修改构建方法以合并这些新类型。

If there is a better way to do it I'm all ears. 如果有更好的方法,我会全力以赴。

Thanks 谢谢

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();
        }
    }
}

Basicly you should get all the types from collections using Linq and then compair the result. 基本上你应该使用Linq从集合中获取所有类型,然后对结果进行计算。

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

It is not clear, should you compair only types of instruments or quantity also. 目前尚不清楚,您是否应仅仅对类型的工具或数量进行比较。 My answer assume you don't care about quantity and you can build with one spanner when you require two. 我的回答是假设你不关心数量,当你需要两个时,你可以用一个spanner建造。

-Update -Update

To comply the requirement about subclasses (Sriram Sakthivel mentioned it) you can check if available tool type is subclass to required tool type so you can use any SpecialSpanner when you need a Spanner 为了符合关于子类的要求(Sriram Sakthivel提到它),您可以检查可用的工具类型是否是所需工具类型的子类,以便在需要Spanner时可以使用任何SpecialSpanner

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 method: 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;
}
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
}

Note:This will fail if you provide more derived type than expected type. 注意:如果您提供的衍生类型多于预期类型,则此操作将失败。 For example if you provide SpecialSpanner in place or Spanner this won't work. 例如,如果您提供SpecialSpannerSpanner这将无法正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM