匿名类型列表或对象列表

时间:2012-07-26 19:03:12

标签: c# asp.net-mvc json list object

我有以下问题(简化)。

我有一份狗的名单:

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

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

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

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

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

但是,由于列表被强列为dogs列表,我首先想到的是创建列表dogscars有一个共同点,他们都是对象

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

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

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

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

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

感谢您一如既往的帮助!

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

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

5 个答案:

答案 0 :(得分: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进行了编辑

答案 1 :(得分:3)

我不太清楚汽车的位置,以及为什么你不能将你的房产改为List<object>,但你可以这样做:

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

或在C#4中,您可以使用通用协方差,只需写:

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

答案 2 :(得分: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; }
    }
}

然后,您将使用List<ICoated>来访问全部涂有物体的对象。显然,如果你有许多共同的属性,那么你就可以适当地扩展这个模型。

答案 3 :(得分: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; }

(宠物)思考的食物

答案 4 :(得分:1)

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

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.
    }
}

这使您在投射前了解自己的类型是安全的。那么你所拥有的汽车类型与狗不同的任何属性。您可以轻松,安全地访问!