简体   繁体   中英

Check and compare two objects

I have a Buildable abstract class from which inherits the classes House and Road.

I'm trying to classify an array of Buildable objects which contains Houses and Roads.

I know that I can check if a object is a Road like this: f(myBuildables[i] is Road) and it works perfectly, but for scalability reasons I want to have an array that contains the classes that inherits from Buildable. I try some stuff but obviously it doesen't work: class[] inheritTypes = { House, Road }

I have also tryied with an array of Types Types[] buildableTypes = { typeOf(Hosue), typeOf(Road) } but I cant compare the types because of typeOf(myBuildables[i]) always returns Buildable type.

The equivalent functionality of a is check on instances but for types is Type.IsAssignableFrom ( docs ).

In your case:

if (typeof(House).IsAssignableFrom(obj.GetType()))
{
//obj is a house
}

So you can keep the types in an array and then make your decisions dynamically based on the contents of that array.

Given

public abstract class Buildable{}

class Road : Buildable{}
class House : Buildable{}

You can do the following

List<Buildable> buildables = new List<Buildable>();
buildables.Add(new House());
buildables.Add(new Road());
buildables.Add(new House());

foreach(var item in buildables)
{
    if(item is House)
    {
        Console.WriteLine("House");
    }
    if (item is Road)
    {
        Console.WriteLine("Road");
    }
}

Or in C# 8.0 you can do advanced pattern matching like the following:

abstract class Buildable { 
    public bool Damage;
}

class Road : Buildable { }
class House : Buildable { }

And pattern match with:

List<Buildable> buildables = new List<Buildable>();
buildables.Add(new House());
buildables.Add(new Road());
buildables.Add(new House{  Damage = true });

foreach (var item in buildables)
{
    switch (item)
    {
        case House damageHouse when damageHouse.Damage:
            Console.WriteLine("House Damaged");
            break;
        case House house:
            Console.WriteLine("House");
            break;
        case Road road:
            Console.WriteLine("Road");
            break;
        case Buildable _:
            Console.WriteLine("Default");
            break;
    }

}

you should use object.GetType ():

myBuildables [I] .GetType ();

Here is a sample code:

 class Program
    {
        abstract class Buildable
        {
            public string Name { get; set; } = string.Empty;
        }

        class Home : Buildable{}

        class Roard: Buildable{}

        static void Main(string[] args)
        {
            List<Type> listTypes = new List<Type>()
            {
                typeof(Home),
            };

            List<Buildable> listBuildable = new List<Buildable>()
            {
                new Home(){Name = "home 1"},
                new Home(){Name = "home 2"},
                new Home(){Name = "home 3"},
                new Roard(){Name = "road 1"},
                new Roard(){Name = "road 2"},
                new Roard(){Name = "road 3"},
            };
            foreach(var item in listBuildable)
            {
                var itemType = item.GetType();
                Console.WriteLine("Buildable name = " + item.Name);
                Console.Write("item typeof" + itemType.ToString());

                if (listTypes.Find(o => o.Equals(itemType)) != null)
                    Console.WriteLine(" - Type isset in list");
                else
                    Console.WriteLine(" - Unknown type");

                Console.WriteLine();

            }
            Console.ReadLine();
        }
    }

Result:

Buildable name = home 1 item typeofConsoleApp1.Program+Home - Type isset in list

Buildable name = home 2 item typeofConsoleApp1.Program+Home - Type isset in list

Buildable name = home 3 item typeofConsoleApp1.Program+Home - Type isset in list

Buildable name = road 1 item typeofConsoleApp1.Program+Roard - Unknown type

Buildable name = road 2 item typeofConsoleApp1.Program+Roard - Unknown type

Buildable name = road 3 item typeofConsoleApp1.Program+Roard - Unknown type

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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