Dictionary and KeyValuePair关系

本文深入解析了C#中Dictionary的内部结构及使用方法,重点介绍了如何利用KeyValuePair来遍历Dictionary集合,展示了通过foreach语句访问键值对的具体实现。

简单一句话: Dictionary 是 由 KeyValuePair结构 组成的集合 

The Dictionary<TKey, TValue>.Enumerator.Current property returns an instance of this type.

The foreach statement of the C# language (for each in C++, For Each in Visual Basic) requires the type of the elements in the collection. Since each element of a collection based on IDictionary<TKey, TValue> is a key/value pair, the element type is not the type of the key or the type of the value. Instead, the element type is KeyValuePair<TKey, TValue>. For example:

C#
C++
VB
 
foreach( KeyValuePair<string, string> kvp in myDictionary )
{
    Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}

The foreach statement is a wrapper around the enumerator, which allows only reading from, not writing to, the collection.

private void InternalCleanOnGo(Job pureJob) { // <><> // <> yangy 20180830: clean on go, assert 'pureJob' is the first job without pre-job in context. // <><> if (pureJob == null) { Coordinator.GetIns().GetLogger().WarnFormat("TaskManager::InternalCleanOnGo(): Input job is null."); return; } if (!pureJob.IsPureJob) { Coordinator.GetIns().GetLogger().WarnFormat("TaskManager::InternalCleanOnGo(): Input job '{0}({1})' is NOT a pure job.", pureJob.Name, pureJob.ID); return; } if (!pureJob.IsInSrcJob) { return; // <> input pure job is NOT in source now } // 1. build clean on go info base on input pure-job // Dictionary<ProcessChamber, string> cleanOnGoInfo = new Dictionary<ProcessChamber, string>(); // 筛选处理的腔室 foreach (Module module in ModuleManager.GetIns().Modules.Values) { //if (!(module is ProcessChamber) || (module is LoadLock)) if (!(module is ProcessChamber)) // xianghf_20200806 { continue; // skip non-processchamber and loadlock } // <> yangy 20181129 // if (module.State != ModuleState.Online) { Coordinator.GetIns().GetLogger().WarnFormat("TaskManager::InternalCleanOnGo(): Skip module '{0}' for it is NOT online.", module.Name); continue; } //if (!cleanOnGoInfo.ContainsKey(module.Name)) //{ // cleanOnGoInfo.Add(module.Name, ""); // add module into 'cleanOnGoInfo' //} //else if (!string.IsNullOrEmpty(cleanOnGoInfo[module.Name])) //{ // continue; //} ProcessChamber pm = (ProcessChamber)module; // assert if (!cleanOnGoInfo.ContainsKey(pm)) { cleanOnGoInfo.Add(pm, ""); // add module into 'cleanOnGoInfo' } else if (!string.IsNullOrEmpty(cleanOnGoInfo[pm])) { continue; // <> if next-recipe is NOT empty, skip and goto next one } foreach (NMC.Scheduling.Route route in pureJob.OriginalRoutes.Values) // <> check all routes { if (route == null) { continue; // skip null route } List<NMC.Scheduling.Visit> visits = route.GetVisits(module.Name); foreach (NMC.Scheduling.Visit visit in visits) { // <> zhuanglu 20200114: need to found first none empty recipe in one job when it may contains more than one route, make this use same logic with Job::PreCheck() //if (!string.IsNullOrEmpty(visit.ProcessRecipe) && (string.IsNullOrEmpty(cleanOnGoInfo[pm].ToString())) ) if (!string.IsNullOrEmpty(visit.ProcessRecipe) && (string.IsNullOrEmpty(cleanOnGoInfo[pm]))) { cleanOnGoInfo[pm] = visit.ProcessRecipe; // found first none empty recipe ID break; } } } } // 2. Restore all job mode // if (this.mIsOverwriteAllInSrcJobMode) { List<Job> pureJobs = new List<Job>(); foreach (Task task in this.mTaskList.Values) // 遍历task { Job job = task as Job; if (job == null) { continue; } if (job.IsPureJob) { pureJobs.Add(job); if (job.IsInSrcJob) { job.RestoreMode(); } } } // <> yangy: requeue all jobs by 'Original Job Mode' // foreach (Job job in pureJobs) { job.RequeuePostJobByOrigMode(); // 重新排队 } this.mIsOverwriteAllInSrcJobMode = false; // reset anyway this.mOverwriteJobMode = JobMode.Pipeline; // reset anyway } // <> yangy 20181101: clean on go (with 100kwh auto burn in) CIP // if (cleanOnGoInfo.Count > 0) // 有模块进行清洁 { // <> contains guessed about to 'burn-in' module info bool isJobNoVisit4CleanOnGo = false; // 遍历路线 foreach (KeyValuePair<int, NMC.Scheduling.Route> kvp in pureJob.OriginalRoutes) // <> check all routes of input 'pureJob' again { if (kvp.Value == null) { continue; // skip null route } NMC.Scheduling.Route deepCloneRoute = new NMC.Scheduling.Route(kvp.Value); // a deep List<ProcessChamber> cleanOnGoPMs = new List<ProcessChamber>(); foreach (KeyValuePair<ProcessChamber, string> kvp1 in cleanOnGoInfo) { if (!string.IsNullOrEmpty(kvp1.Value)) { deepCloneRoute.RemoveModule(kvp1.Key.Name); // remove module with 'next recipe' if (!cleanOnGoPMs.Contains(kvp1.Key)) { cleanOnGoPMs.Add(kvp1.Key); } } } for (int i = 0; i < deepCloneRoute.GetStepNum(); i++) // <> check all steps of 'deepCloneRoute' after removing about-to-clean module { // 移除后不可访问,job在cleanongo中无法进行 if (deepCloneRoute.GetStep(i).GetVisitNum() <= 0) { isJobNoVisit4CleanOnGo = true; Coordinator.GetIns().GetLogger().WarnFormat("TaskManager::InternalCleanOnGo(): Guess input job '{0}({1})' will have no way to go for route '{2}' in slot '{3}' during the clean-no-go.", pureJob.Name, pureJob.ID, deepCloneRoute.Name, kvp.Key); break; } } if (isJobNoVisit4CleanOnGo) { //pureJob.IsHeldByCleanOnGo = true; // xianghf_20200806 //pureJob.CleanOnGoModules = cleanOnGoModules; // 初始化CleanOnGo列表 pureJob.InitCleanOnGoPMs(cleanOnGoPMs); break; } } //this.mPending4CleanOnGoModules.Clear(); } // xianghf_20200806 pureJob.IsHeldByCleanOnGo = true; // <><><> yangy: set 'IsHeldByCleanOnGo' anyway for Trans/Buff do auto ROR ?? <><><> // 3. clean on go // foreach (KeyValuePair<ProcessChamber, string> kvp in cleanOnGoInfo) { Coordinator.GetIns().GetLogger().WarnFormat("TaskManager::InternalCleanOnGo(): Begin clean-on-go on '{0}' with next recipe '{1}'.", kvp.Key.Name, kvp.Value); this.HandleNewMove(new CleanOnGoMove(kvp.Key.Name, kvp.Value), false); Coordinator.GetIns().GetLogger().WarnFormat("TaskManager::InternalCleanOnGo(): End clean-on-go on '{0}' with next recipe '{1}'.", kvp.Key.Name, kvp.Value); } // xianghf_20200806: for TransferRobot cleanongo // foreach (string mod in pureJob.Modules) { Module module = ModuleManager.GetIns().Modules[mod]; if (module is TransferRobot) { Coordinator.GetIns().GetLogger().WarnFormat("TaskManager::InternalCleanOnGo(): Begin clean-on-go on '{0}'.", module.Name); this.HandleNewMove(new CleanOnGoMove(module.Name, ""), false); Coordinator.GetIns().GetLogger().WarnFormat("TaskManager::InternalCleanOnGo(): End clean-on-go on '{0}'.", module.Name); } } }详细解释代码
最新发布
08-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值