本例子实现了如何自定义线性节点集合,具体代码如下:

using System;
using System.Collections;
using System.Collections.Generic; namespace LineNodeDemo
{
class Program
{
static void Main(string[] args)
{
LineNodeCollection lineNodes = new LineNodeCollection();
lineNodes.Add(new LineNode("N1") { Name = "Microsoft" });
lineNodes.Add(new LineNode("N2") { Name = "Lenovo" });
lineNodes.Add(new LineNode("N3") { Name = "Apple" });
lineNodes.Add(new LineNode("N4") { Name = "China Mobile" });
Console.WriteLine("1、显示全部:");
lineNodes.ForEach(x => { Console.WriteLine(x.Name); });
Console.WriteLine("2、删除编号为N2的元素:");
lineNodes.Remove("N2");
lineNodes.ForEach(x => { Console.WriteLine(x.Name); });
Console.WriteLine("3、删除索引为1的元素:");
lineNodes.RemoveAt();
lineNodes.ForEach(x => { Console.WriteLine(x.Name); });
Console.WriteLine("4、显示索引为0元素的名称:");
Console.WriteLine(lineNodes[].Name);
Console.WriteLine("5、显示编号为N4元素的名称:");
Console.WriteLine(lineNodes["N4"].Name);
Console.WriteLine("6、清空");
lineNodes.Clear();
lineNodes.ForEach(x => { Console.WriteLine(x.Name); });
Console.ReadKey();
}
} static class Utility
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach(var r in source)
{
action(r);
}
}
} class LineNodeCollection : IEnumerable<LineNode>
{
public IEnumerator<LineNode> GetEnumerator()
{
return new LineNodeEnumerator(this.firstLineNode);
} IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
} public LineNode this[int index]
{
get
{
LineNode _lineNode= this.firstLineNode;
for (int i=;i<=index;i++)
{
if (_lineNode != null)
{
if(i<index)
{
_lineNode = _lineNode.Next;
continue;
}
else
{
return _lineNode;
}
}
else break;
}
throw new IndexOutOfRangeException("超出集合索引范围");
}
} public LineNode this[string id]
{
get
{
LineNode _lineNode = this.firstLineNode;
for (int i = ; i < this.Count; i++)
{
if(_lineNode.ID == id)
{
return _lineNode;
}
else
{
_lineNode = _lineNode.Next;
}
}
throw new IndexOutOfRangeException("未能在集合中找到该元素");
}
} LineNode firstLineNode;
LineNode lastLineNode;
public void Add(LineNode lineNode)
{
this.Count++;
if(this.firstLineNode == null)
{
this.firstLineNode = lineNode;
}
else
{
if (this.firstLineNode.Next == null)
{
lineNode.Previous = this.firstLineNode;
this.firstLineNode.Next = lineNode;
this.lastLineNode = this.firstLineNode.Next;
}
else
{
lineNode.Previous = this.lastLineNode;
this.lastLineNode.Next = lineNode;
this.lastLineNode = this.lastLineNode.Next;
}
}
} public int Count
{
private set;get;
} public int IndexOf(string id)
{
LineNode _lineNode = this.firstLineNode;
for (int i = ; i < this.Count; i++)
{
if (_lineNode.ID == id)
{
return i;
}
else
{
_lineNode = _lineNode.Next;
}
}
throw new IndexOutOfRangeException("未能在集合中找到该元素");
} public void Clear()
{
this.firstLineNode = null;
this.lastLineNode = null;
this.Count = ;
this.GetEnumerator().Reset();
} public void RemoveAt(int index)
{
if (this.Count < index) throw new InvalidOperationException("超出集合索引范围");
LineNode _currentLineNode = this[index];
if (_currentLineNode.Previous == null)
{
_currentLineNode = _currentLineNode.Next;
this.firstLineNode = _currentLineNode;
}
else
{
LineNode _lineNode = this.firstLineNode;
for (int i = ; i <= index - ; i++)
{
if (i < index - )
{
_lineNode = _lineNode.Next;
continue;
}
if (i == index - )
{
if (_currentLineNode.Next != null)
{
_lineNode.Next = _lineNode.Next.Next;
}
else
{
this.lastLineNode = _lineNode;
_lineNode.Next = null;
}
break;
}
}
}
this.Count--;
} public void Remove(string id)
{
int _index = this.IndexOf(id);
this.RemoveAt(_index);
} public LineNode TopLineNode { get { return this.firstLineNode; } }
public LineNode LastLineNode { get { return this.lastLineNode; } }
} class LineNodeEnumerator : IEnumerator<LineNode>
{
LineNode topLineNode;
public LineNodeEnumerator(LineNode topLineNode)
{
this.topLineNode = topLineNode;
}
public LineNode Current
{
get
{
return this.lineNode;
}
} object IEnumerator.Current
{
get
{
return this.Current;
}
} public void Dispose()
{
this.lineNode = null;
} LineNode lineNode; public bool MoveNext()
{
if(this.lineNode == null)
{
this.lineNode = this.topLineNode;
if (this.lineNode == null) return false;
if (this.lineNode.Next == null)
return false;
else
return true;
}
else
{
if(this.lineNode.Next !=null)
{
this.lineNode = this.lineNode.Next;
return true;
}
return false;
}
} public void Reset()
{
this.lineNode = null;
}
} class LineNode
{
public LineNode(string id)
{
this.ID = id;
}
public string ID { private set; get; }
public string Name {set; get; }
public LineNode Next { set; get; }
public LineNode Previous { set; get; }
}
}

注意:

①这里所谓的线性节点指定是每个节点之间通过关联前后节点,从而形成链接的节点;

②本示例完全由博主原创,转载请注明来处。

运行结果如下:

示例下载地址:https://pan.baidu.com/s/1eS9UIzS

(请使用VS2015打开,如果为其他版本,请将Program.cs中的内容复制到自己创建的控制台程序中)

C# 基于泛型的自定义线性节点链表集合示例的更多相关文章

  1. Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)

    很久没有写博客了,一些读者也经常问问一些问题,不过最近我确实也很忙,除了处理日常工作外,平常主要的时间也花在了继续研究微软的实体框架(EntityFramework)方面了.这个实体框架加入了很多特性 ...

  2. VS2012 常用web.config配置解析之自定义配置节点

    在web.config文件中拥有一个用户自定义配置节点configSections,这个节点可以方便用户在web.config中随意的添加配置节点,让程序更加灵活(主要用于第三方插件的配置使用) 自定 ...

  3. C#创建自定义配置节点

    转载:http://www.educity.cn/develop/495003.html 在.Net应用程序中我们经常看到VS为我们生成的项目工程中都会含有app.config或者web.connfi ...

  4. 基于HTML5 Canvas的线性区域图表教程

    之前我们看到过很多用jQuery实现的网页图表,有些还是比较实用的.今天我们来介绍一款基于HTML5 Canvas的线性区域图表应用,这个图表应用允许你使用多组数据来同时展示,并且将数据结果以线性图的 ...

  5. App.config和Web.config配置文件的自定义配置节点

    前言 昨天修改代码发现了一个问题,由于自己要在WCF服务接口中添加了一个方法,那么在相应调用的地方进行更新服务就可以了,不料意外发生了,竟然无法更新.左查右查终于发现了问题.App.config配置文 ...

  6. C#自定义配置文件节点

    老实说,在以前没写个自定义配置节点之前,我都是写到一个很常用的节点里面,就是appSettings里add,然后再对各个节点的value值进行字符串分割操作,根据各种分割字符嵌套循环处理,后来看到一些 ...

  7. 基于 HtmlHelper 的自定义扩展Container

    基于 HtmlHelper 的自定义扩展Container Intro 基于 asp.net mvc 的权限控制系统的一部分,适用于对UI层数据呈现的控制,基于 HtmlHelper 的扩展组件 Co ...

  8. springboot读取自定义配置文件节点

    今天和大家分享的是自定义配置信息的读取:近期有写博客这样的计划,分别交叉来写springboot方面和springcloud方面的文章,因为springboot预计的篇章很多,这样cloud的文章就需 ...

  9. 基于django的自定义简单session功能

    基于django的自定义简单session功能 简单思路: 1.建立自定义session数据库 2.登入时将用户名和密码存入session库 3.将自定义的随机session_id写入cookie中 ...

随机推荐

  1. Linux 同步时间 设置时区

    简化版 同步时间 #直接用域名同步中国上海时间 ntpdate -u ntp.api.bz # hwclock --hctosys 或者 # clock --hctosys hc代表硬件时间,sys代 ...

  2. Session["Write"] = "Write";

    Session["Write"] = "Write"; 将Session使用起来,建立起回话,这样才能保证会话中保持SessionID不变,否者,如果你直接使用 ...

  3. SQL Server 跨网段(跨机房)通过备份文件初始化复制

    笔者最近碰到了需要搭建跨网段的SQL Server复制,实际的拓扑结构如下草图所示: 发布端A服务器位于CDC机房中 订阅端B服务器位于阿里云 因为SQL Server复制不支持通过IP连接分发服务器 ...

  4. linux 通过 mac地址 查询 ip 和 清除arp 缓存

    问题重述: 今天,突然找不到vm 的ip 了,但是可以从网卡状态上看到其 mac 地址,并且确定主机是启动状态,网络状态良好(后来发现因为子网掩码的问题,导致虚拟机和网关之间不通信,从而导致其他网络的 ...

  5. 另开一篇 https

    https 流程 1.加密传输:对称加密传输信息 2.身份认证:非对称加密.通过证书来保障客户端给服务器的密钥唯一性. 因为中间层要是伪装公钥和证书,但是又无法解密原有的发送的数据,那么发给服务器的数 ...

  6. Javaweb学习(二):Http通信协议

      当我们开始jsp/servlet编程之旅之前,我们还需要知道一些关于网络通讯方面的一些知识.这样能更加有助于我们的理解,希望大家能看懂我的描述,而不至于在学习的路上一知半解.(手动比❤) 认识Ht ...

  7. python3: 文件与IO

    1.读写文本数据 # Write chunks of text data with open('somefile.txt', 'wt') as f: f.write(text1) # Redirect ...

  8. Nginx实践--安全升级

    之前写了一些nginx的东西,这次继续,主要使用upstream针对proxy_pass转发做个处理 一般情况下我们在使用nginx反向代理的时候,都是如下配置, ... location /api ...

  9. (十九)ArcGIS JS 加载WMS服务(超图示例)

    前言 在工作中,需要在ArcGIS API for JavaScript中加载超图服务,因为超图的rest服务只可以用于Leaflet .openlayers3 (with MVT) .MapboxG ...

  10. ocr jdk

    公司有个需求,遍历所有图片,筛选出含有敏感字的图片.这里就需要ocr技术,找了几天,发现了几个不错的ocr jdk. http://cn.ocrsdk.com/ 俄罗斯公司,贵有贵的道理 http:/ ...