c# - 在任何访问(foreach 等)上自动对 List<> 中的元素执行特定操作
问题描述
基本描述和上下文:
从结构上讲,有一个数据库对象具有对象列表(基本上每个列表都是一个表),并且所述列表的每个成员都可以有自己的列表。
所有 XML 内容都在后台完成,因此编码人员不必担心这一点。
如果列表中的对象有自己的一个或多个列表,则在object.open()
调用之前它们是空的(将数据从 XML 加载到内存)。
问题是导航这个结构。如果我可以调用类似GetLazilyInitializedXX()
的方法会返回一个具有相同引用的新列表,但是当访问任何成员时它具有自动操作(但仅在那时。不是所有的,除非 foreach 真的经过所有这些,否则会很棒)例如!)。类似的东西LazyList<>
。
使用示例:我需要从结构的更深部分找到最新的yCount
(代码中调用的)数据。amount
列表从最早的记录日期到最新的排序。所以目前我必须创建一个顺序相反的新列表,在每个后续列表上使用 foreach 并手动调用.open()
列表成员,并在yCount
达到时返回选择。
如果列表中的对象在.open()
从这样的“LazyList”中被访问/获取(以任何方式,即即使在 foreach 中,并且只有那些真正被“获取”的对象)时,则可以使用“select / where”(即使在foreach),简化了很多代码并删除了很多嵌套。
当前 WIP 代码(有大量嵌套):
/// <summary>
/// Gets the latest Daily Test Data.
/// </summary>
/// <param name="amount">The amount of Daily Tests to get</param>
/// <param name="fromDateTime">The date to get Daily Tests from (default - today)</param>
/// <returns></returns>
public static List<QCUnitDailyTestData> GetLatestDailyTestData(int amount = 1, DateTime? fromDateTime = null)
{
List<QCUnitDailyTestData> result = new List<QCUnitDailyTestData>();
//Removing the time from the date. If fromDateTime is null, using current DateTime
var fromDate = fromDateTime?.Date ?? DateTime.Now.Date;
Log.Info("Selecting " + amount + " latest Daily Tests from: " + fromDate); //todo format fromDate?
//We need to go through years from the latest to oldest.
foreach (ProductionYear productionYear in Database.GetProductionYearsFromLatest())
{
//LazyInit!
productionYear.Open();
//We need to go through days from the latest to oldest.
foreach (ProductionDay productionDay in productionYear.GetProductionDaysFromLatest())
{
//LazyInit!
productionDay.Open();
//If the production day is before fromDate or it is the same day as fromDate...
if (productionDay.Data.Date.Date.CompareTo(fromDate) < 1)
{
//We only want the newest daily test. The other ones (in the same day) aren't used!
QCUnitDailyTest dailyTest = productionDay.GetDailyTestsFromLatest().FirstOrDefault();
//A day doesn't have to have a daily test - if there is no daily test, continue with the next day
if (dailyTest == null) continue;
//LazyInit!
dailyTest.Open();
result.Add(dailyTest.Data); //Adding to the resulting list
//If we have enough, we return the resulting list
if (result.Count == amount)
{
Log.Info("Selection completed successfully.");
return result;
}
}
}
}
//if there are no Daily Tests matching our criteria, or there weren't enough of them, we return either an empty
// list or those we found
int count = result.Count;
Log.Warn(count == 0 ? "No Daily Tests were found." : "Only " + count + " Daily Tests were found.");
return result;
}
解决方案
我确实解决了它,但该解决方案非常特定于我们的“数据库”,主要问题是 - 如何在以任何方式访问所述元素时自动使用 List<> 元素执行操作。
数据控制器:
/// <summary>
/// Gets the latest Daily Test Data.
/// </summary>
/// <param name="amount">The amount of Daily Tests to get. Default - 1</param>
/// <param name="fromDateTime">The date to get Daily Tests from (default - today)</param>
/// <returns></returns>
public static List<QCUnitDailyTestData> GetLatestDailyTestData(int amount = 1, DateTime? fromDateTime = null)
{
List<QCUnitDailyTestData> result = new List<QCUnitDailyTestData>();
//Removing the time from the date. If fromDateTime is null, using current DateTime
var fromDate = fromDateTime?.Date ?? DateTime.Now.Date;
Log.Info("Selecting " + amount + " latest Daily Tests from: " + fromDate); //todo format fromDate?
//We need to go through years, days and daily tests from the latest to oldest.
foreach (var dailyTest in
from productionYear in Database.GetProductionYearsFromLatest()
from productionDay in productionYear.GetProductionDaysFromLatest()
where productionDay.GetData().Date.Date.CompareTo(fromDate) < 1 //If the production day is before fromDate or it is the same day as fromDate...
select productionDay.GetDailyTestsFromLatest().FirstOrDefault()//We only want the newest daily test. The other ones (in the same day) aren't used!
into dailyTest where dailyTest != null /*A prod. day doesn't have to have a daily test*/ select dailyTest)
{
result.Add(dailyTest.GetData()); //Adding to the resulting list
//If we have enough, we return the resulting list
if (result.Count == amount)
{
Log.Info("Selection completed successfully.");
return result;
}
}
//if there are no Daily Tests matching our criteria, or there weren't enough of them, we return either an empty
// list or those we found
int count = result.Count;
Log.Warn(count == 0 ? "No Daily Tests were found."
: "Only " + count + " Daily Tests were found.");
return result;
}
数据.生产年份:
/// <summary>
/// <see cref="Days"/> lists <see cref="ProductionDay"/> instances.
/// </summary>
private readonly List<ProductionDay> Days = new List<ProductionDay>();
/// <summary>
/// For LazyInits - opens the year on access to days
/// </summary>
/// <returns></returns>
public List<ProductionDay> GetDays()
{
if (!Opened) Open();
return Days;
}
/// <summary>
/// Returns A NEW INSTANCE of production days, with the order from latest to newest
/// </summary>
/// <returns>See summary</returns>
public List<ProductionDay> GetProductionDaysFromLatest()
{
List<ProductionDay> days = new List<ProductionDay>(GetDays());
days.Sort((day1, day2) => day1.GetDate(true).CompareTo(day2.GetDate(true)));
return days;
}
只是为了完整起见 Data.ProductionDay:
private DateTime Date => Data.Date; //Nullpointer when the day isn't opened
private DateTime DateLazy;
/// <summary>
/// If closed, return DataLazy instead of Data.Date, unless lazyStrict is false
/// </summary>
/// <returns>See summary</returns>
public DateTime GetDate(bool lazyStrict = false)
{
if (!Opened && !lazyStrict)
{
Open();
return Data.Date;
}
return Data?.Date ?? DateLazy;
}
但正如我所说,这个解决方案非常适合我们的项目。
编辑:格式(括号......)也有点搞砸了。它们不在编码环境中(JetBrains Rider),所以我可能会把它们原封不动地保留在这里,带着它们所有的古怪荣耀。
EDIT2:此外,为年和日提供的代码不是整个课程,只有相关部分。
推荐阅读
- javascript - 网站状态总是显示禁止,我该怎么办?
- python - Scrapy Project - 如何使用 - 带有暂停和恢复开关的“项目和管道”抓取、抓取嵌套关系数据并将其导出到 CSV?
- android - 沿着 latlng 点列表平滑地为谷歌地图标记设置动画
- javascript - Javascript画布,颜色未正确应用
- php - 自定义消息验证正则表达式 Laravel
- reactjs - React.js - CORS 策略:请求的资源上不存在“Access-Control-Allow-Origin”标头。[AWS - Lambda - API 网关]
- node.js - 如何减少电子邮件发送时间(使用 nodemailer 和 firebase)?
- pandas - 将数据框与日期时间窗口连接起来
- reactjs - axios 默认标头和 transformRequest 可能存在的错误
- google-cloud-platform - 如何在大查询表的字段中列出值?