我有第一个这样的实体列表:
public partial class Networking :EntityBase
{
public virtual int NetWorkingId
{
get;
set;
}
public virtual string NetWorkingParam
{
get;
set;
}
public virtual System.DateTime NetWorkingDate
{
get;
set;
}
}
我有第二个这样的实体列表:
public partial class PrivateNetwork :EntityBase
{
public virtual int PrivateNetworkId
{
get;
set;
}
public virtual int ContaId
{
get { return _contaId; }
set
{
if (_contaId != value)
{
if (Contact != null && Contact.ContaId != value)
{
Contact = null;
}
_contaId = value;
}
}
}
public virtual Nullable<System.DateTime> DateCreation
{
get;
set;
}
}
我想在一个中收集这两个列表,并按日期对所有元素进行排序。
这可能吗?
答案 0 :(得分:5)
使用多态可以很容易地解决这个问题;为这两个类使用公共基类或接口,它具有您要排序的DateTime
属性。
示例:
public abstract class NetworkingBase : EntityBase
{
public DateTime DateToSortOn { get; set; }
}
或
public interface INetworking
{
public DateTime DateToSortOn { get; set; }
}
然后让您的课程来自NetworkingBase
或实施INetworking
:
public partial class Networking : NetworkingBase
{
...
}
public partial class PrivateNetwork : NetworkingBase
{
...
}
或
public partial class Networking : EntityBase, INetworking
{
...
}
public partial class PrivateNetwork : EntityBase, INetworking
{
...
}
答案 1 :(得分:5)
你可以做到这一点,虽然它不是很漂亮,你最终得到IEnumerable<object>
所以你必须检查每个项目的类型才能使用它:
IEnumerable<object> sorted = myNetworkingList
.Concat<object>(myPrivateNetworkList)
.OrderBy(n => n is Networking
? (DateTime?)((Networking)n).NetWorkingDate
: ((PrivateNetwork)n).DateCreation);
foreach (object either in sorted)
{
if (either is Networking)
// Networking; do something
else
// PrivateNetwork; do something else
}
答案 2 :(得分:2)
我之前应该问的是。 。 。
排序后你想做什么?
这个问题的答案可能会对潜在的解决方案产生重大影响。
如果答案类似于,我需要显示日期列表,您只需要按顺序排列日期。如果是这样,那么你不需要合并两个列表,你可以得到一个只是有序日期的序列并使用它。例如。
var orderedDates = networks.Select(n => n.NetworkingDate)
.Union(privateNetworks.Select(n => n.DateCreation))
.OrderBy(date => date);
如果答案是我需要显示一个链接列表,显示链接到对象ID的日期,以及识别对象类型的东西,那么你可以侥幸逃脱非常喜欢上面的,有一个匿名对象。
var orderedDates = networks.Select(n => new {Date = n.NetworkingDate, Id = n.NetWorkingId, NetworkType = n.GetType().Name})
.Union(privateNetworks.Select(n => new {Date = n.DateCreation, Id = n.PrivateNetWorkingId, NetworkType = n.GetType().Name}))
.OrderBy(n => n.Date);
但是如果答案是我需要向10个最古老的网络发送Shutdown()命令然后你真的需要一个多态解决方案,你有一个您可以调用Shutdown()
方法的类型,该方法将解析为您正在使用的类型的特定Shutdown()
方法。
仅在用户khellang's answer不适合您时使用的多态解决方案
来自对另一个答案的评论
@BinaryWorrier我选择了这个答案,因为我已经有了记录 数据库,所以如果我选择添加一个新的界面我将如何处理 在添加界面之前已经存储了记录吗?
我发现很难相信你的ORM不会允许你向实体类添加接口而不是 - 不知何故 - 标记该接口和/或它的成员,以便它们被ORM忽略。
但是,假设您无法添加新接口或基类,您仍然可以多态地执行此操作。
添加接口,添加一个实现每个网络类(Abstractor
类)的接口的类,然后将网络类转换为Abstractor
类,将它们添加到{{1并排序该列表。
List<INetwork>
答案 3 :(得分:1)
创建一个在两个类中都有日期和实现的接口。之后排序很容易。
public interface INetwork
{
DateTime? Date { get; }
}
public partial class Networking :EntityBase, INetwork
{
public DateTime? Date
{
get { return NetWorkingDate; }
}
}
public partial class PrivateNetwork :EntityBase, INetwork
{
public DateTime? Date
{
get { return DateCreation; }
}
}
var commonList = new List<INetwork>();
// Add instances of PrivateNetwork and Networking to the list
var orderedByDate = commonList.OrderBy(n => n.Date);
答案 4 :(得分:0)
第一种解决方案是使用匿名类型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Example1
{
class Program
{
class Human
{
public string Name { get; set; }
public string Hobby { get; set; }
public DateTime DateOfBirth { get; set; }
}
class Animal
{
public string Name { get; set; }
public string FavouriteFood { get; set; }
public DateTime DateOfBirth { get; set; }
}
static void Main(string[] args)
{
var humans = new List<Human>
{
new Human
{
Name = "Kate",
Hobby = "Fitness",
DateOfBirth = DateTime.Now.AddYears(-27),
},
new Human
{
Name = "John",
Hobby = "Cars",
DateOfBirth = DateTime.Now.AddYears(-32),
},
};
var animals = new List<Animal>
{
new Animal
{
Name = "Fluffy",
FavouriteFood = "Grain",
DateOfBirth = DateTime.Now.AddYears(-2),
},
new Animal
{
Name = "Bongo",
FavouriteFood = "Beef",
DateOfBirth = DateTime.Now.AddYears(-6),
},
};
var customCollection = (from human in humans
select new
{
Name = human.Name,
Date = human.DateOfBirth,
}
).Union(from animal in animals
select new
{
Name = animal.Name,
Date = animal.DateOfBirth,
}).OrderBy(x => x.Date);
foreach (dynamic customItem in customCollection)
Console.WriteLine(String.Format("Date: {0}, Name: {1}", customItem.Date, customItem.Name));
Console.Read();
}
}
}
或没有匿名类型(创建CustomClass):
...
class CustomClass
{
public string Name { get; set; }
public DateTime Date { get; set; }
}
...
var customCollection = (from human in humans
select new CustomClass
{
Name = human.Name,
Date = human.DateOfBirth,
}
).Union(from animal in animals
select new CustomClass
{
Name = animal.Name,
Date = animal.DateOfBirth,
}).OrderBy(x => x.Date);
foreach (CustomClass customItem in customCollection)
Console.WriteLine(String.Format("Date: {0}, Name: {1}", customItem.Date, customItem.Name));
...
答案 5 :(得分:0)
我只是添加了一个基类并将其指定为两个列表类的父类。然后简单地做了工会。它成功了