2

我有以下问题(简化)。

我有一张狗的名单:

public List<Dog> dogs { get; set; }

我目前通过在视图中将其转换为 json 对象来访问此列表:

@(new HtmlString(@Json.Encode(@ViewBag.dogs)))

然后我使用 javascript 遍历这个 json 对象并将其显示在页面上。

我想将汽车添加到此列表中。

但是,由于列表是强类型列表,dogs我的第一个想法是将列表创建为一个事物dogscars具有共同点,它们都是 objects

当我尝试将我的狗列表更改为 列表时objects,我收到以下错误

Cannot implicitly convert type 'System.Collections.Generic.List<object>' to System.Collections.Generic.List<dog>

我对此进行了研究,发现这个问题对我没有多大帮助,只是告诉我我无法列出狗和汽车。然而,就我的目的而言,这并不合适。我需要我的列表同时包含狗和汽车,以便我可以在我的应用程序中访问它们。

我预计会建议的一种解决方案是我有两个单独的列表,并发出两个单独的 ajax 请求。但是,我需要按特定顺序(基于它们的创建时间)混合汽车和狗,这样解决方案并不理想。

简而言之,我想知道实现这一目标的最佳方法是什么。也许我走错了方向,所以如果有意义的话,我不反对做一些完全不同的事情。

感谢您一如既往的帮助!

编辑:我已经尝试过演员表并且有效。但是,我需要访问 dog 的属性(我们称之为“毛皮”),我似乎无法做到这一点(我需要再次施法吗?)

'object' does not contain a definition for 'fur'
4

5 回答 5

7

只有当狗和汽车实现相同的接口或扩展相同的类(例如对象,然后您可以在条件下使用 typeof 对它们执行一些操作)时,您才能制作同时包含狗和汽车的列表。

编辑:

简单的例子

using System;
using System.Collections.Generic;

namespace Polymorphism
{
    class Program
    {
        public class Car
        {
            public string Drive()
            {
                return "Wrrrr!";
            }
        }

        public class Dog 
        {
            public string Talk()
            {
                return "Woof";
            }
        }

        static void Main()
        {
            var car = new Car();
            var dog = new Dog();

            List<object> list = new List<object>();
            list.Add(car);
            list.Add(dog);

            foreach (object o in list)
            {
                if (o is Car)
                    Console.WriteLine((o as Car).Drive());
                else
                    Console.WriteLine((o as Dog).Talk());
            }
        }
    }
}

我很抱歉该代码,但我从Wikipedia复制了它并使用Ideone进行了编辑

于 2012-07-26T19:09:39.743 回答
3

我不太清楚汽车从哪里进来,为什么你不能把你的财产改成一List<object>开始,但你可以这样做:

List<object> objects = foo.Dogs.Cast<object>().ToList();

或者在 C# 4 中,您可以使用泛型协方差并编写:

List<object> objects = foo.Dogs.ToList<object>();
于 2012-07-26T19:06:23.003 回答
2

在列表中拥有不同对象并访问它们共有的属性的最简单方法是在类上使用接口。

例如:

public interface ICoated {
    string Coating { get; set; }
}

public class Dog : ICoated {
    public string Coating {
        get { return Fur; }
        set { Fur = value; }
    }
}

public class Car: ICoated {
    public string Coating {
        get { return PaintJob; }
        set { PaintJob = value; }
    }
}

然后,您将使用 aList<ICoated>来访问都涂有某种东西的对象。显然,如果您有许多共同的属性,那么您将适当地扩展此模型。

于 2012-07-26T19:18:10.367 回答
2

尝试找出两个对象之间的共同点并使用基类或接口。如果你使用了一个界面,你可能会看到它看起来像这样:

public interface IAnimal{
   Fur Fur{ get; set; }
   bool CanBark { get; set;}
}

public class Dog : IAnimal {
   public Fur Fur{ get; set; }
   public bool CanBark { get; set;}
}

public class Cat: IAnimal {
   public Fur Fur{ get; set; }
   public bool CanBark { get; set;}
}

public class Fur{
    public string Color {get;set;}
    public int Length {get;set}
}

等等等等

那么,您的列表可以是:

public List<IAnimal> dogs { get; set; }
public List<IAnimal> cats{ get; set; }

(宠物) 深思熟虑

于 2012-07-26T19:18:27.787 回答
1

我可能会创建一个具有共享属性和“类型”属性的接口。

public enum CrazyObjectType
{
    Dog,
    Car
}

public interface ICrazyObject
{
    DateTime Date { get; }
    CrazyOjbectType MyObjectType { get; }
}

public class Dog : ICrazyObject
{
    public Dog()
    {
        MyObjectType = CrazyObjectType.Dog;
    }

    public DateTime Date { get; }
    public CrazyObjectType MyObjectType { get; }
}

public class Car : ICrazyObject
{
    public Car()
    {
        MyObjectType = CrazyObjectType.Car;
    }

    public DateTime Date { get; }
    public CrazyObjectType MyObjectType { get; }
}

然后,List<object>您可以List<ICrazyObject>在投射到汽车或狗之前检查类型,而不是使用它。

foreach (var myObject in myObjects)
{
    if (myObject.MyObjectType == CrazyObjectType.Car)
    {
        var myCar = (Car)myObject;
        //Do Stuff with myCar here.
    }
}

这使您可以安全地在投射之前了解您的类型。然后,您在类型汽车中具有与狗不同的任何属性。您可以轻松、安全地访问!

于 2012-07-26T19:25:03.837 回答