c# - c#中使用扩展方法的单链表
问题描述
- 为什么扩展方法在插入操作中不返回修改的节点。
- 但它在创建链接列表时工作正常。
- 扩展方法应该返回修改后的节点。
- 什么是完美的方法来做到这一点。
- IS扩展方法性能好
代码如下
public class Node
{
public Object Data { get; set; }
public Node NextNode { get; set; }
}
public static class ListOperations
{
public static void CreateLinkedList(this Node node, Object data)
{
if (node.Data == null)
{
node.Data = data;
}
else
{
Node newnode = new Node();
newnode.Data = data;
Node current = new Node();
current = node;
while (current.NextNode != null)
{
current = current.NextNode;
}
current.NextNode = newnode;
node = current;
}
}
public static void InsertNode(this Node node1, Object data, int position)
{
Node newnode = new Node();
newnode.Data = data;
if (position == 1)
{
newnode.NextNode = node1;
node1 = newnode;
}
}
}
class Program
{
static void Main(string[] args)
{
Node node = new Node();
//random Singly LinkedList
node.CreateLinkedList(10);
node.CreateLinkedList(11);
node.CreateLinkedList(12);
node.CreateLinkedList(13);
node.CreateLinkedList(14);
node.CreateLinkedList(15);
node.InsertNode(20, 1);// this method does not return node value what is inserted.
}
}
解决方案
您的代码有很多问题,我们可以稍后处理。但是,让我们先回答您的问题。我会有点直截了当,因为我不能假设你为什么要这样做。
为什么扩展方法在插入操作中不返回修改的节点。
由于您的方法不返回任何内容
但它在创建链接列表时工作正常。
是的,因为该代码从未修改过this Node node
参数
扩展方法应该返回修改后的节点。
仅当您实际从该方法返回任何数据时!
什么是完美的方法来做到这一点。
见下文
IS扩展方法性能好
扩展方法与什么相比?与类似编写的成员方法相比,与您的示例相关的案例应该没有性能差异
完美的方法:
所以首先要做的事情是:这里不需要编写扩展方法。你为什么不写一个普通的成员方法?当您要添加功能的类不能直接供您编辑时,通常会进行扩展,通常是因为代码属于第三方
其次,您似乎不太了解引用以及按值传递的工作原理。先贴一个更好的代码,再解释一下
public class Node {
public object Data { get; set; }
public Node NextNode { get; set; }
public Node(object data) {
Data = data;
}
public Node AppendNode(object data) {
var newNode = new Node(data);
var current = this;
while (current.NextNode != null)
current = current.NextNode;
current.NextNode = newNode;
return newNode;
}
public Node SetFirstNode(object data) {
return new Node(data) { NextNode = this };
}
}
class Program {
static void Main(string[] args) {
var linkedList = new Node(10);
linkedList.AppendNode(11);
linkedList.AppendNode(12);
linkedList.AppendNode(13);
linkedList.AppendNode(14);
linkedList.AppendNode(15);
linkedList = linkedList.SetFirstNode(20);
}
}
从您的主要问题(为什么插入不起作用)的角度要注意的重要事项是该方法SetFirstNode
实际上返回了新创建的节点,并且Main
我们重新分配了链表linkedList = linkedList.SetFirstNode(20);
现在,您实际上可以编写一个静态方法并通过 ref 传递链表,但在我看来,这不是一个好习惯。不过,代码如下所示
public static class ListOperations {
public static void InsertNode(ref Node linkedList, object data) {
linkedList = new Node(data) { NextNode = linkedList };
}
}
除其他需要注意的事项外,我故意将node
对象称为 as linkedList
、CreateLinkedList
asAppendNode
和InsertNode
as SetFirstNode
,以便您可以更好地理解代码。
下面是具有通用参数的相同代码,而不是object Data
使用正确的InsertNode
方法
public class Node<T> {
public T Data { get; set; }
public Node<T> Next { get; set; }
public override string ToString() {
return Data.ToString();
}
public Node(T data) {
Data = data;
}
public Node<T> AppendNode(T data) {
var newNode = new Node<T>(data);
var current = this;
while (current.Next != null)
current = current.Next;
current.Next = newNode;
return newNode;
}
/// <summary>
/// Inserts a new node into the linkedlist as the desired position
/// </summary>
/// <param name="position">0-based index for the final position of new node</param>
/// <param name="newNode">The newly created node containing data</param>
/// <returns>returns the first node of the linkedlist</returns>
public Node<T> InsertNode(T data, int position, out Node<T> newNode) {
var current = this;
position--;
newNode = new Node<T>(data);
if (position < 0) {
newNode.Next = current;
return newNode;
}
for (int i = 0; i < position; ++i)
current = current.Next;
newNode.Next = current.Next;
current.Next = newNode;
return this;
}
}
class Program {
static void Main(string[] args) {
var linkedList = new Node<int>(10);
linkedList.AppendNode(11);
linkedList.AppendNode(12);
linkedList.AppendNode(13);
linkedList.AppendNode(14);
linkedList.AppendNode(15);
linkedList = linkedList.InsertNode(20, 0, out var newNode);
}
}
推荐阅读
- javascript - jQuery 从*所有*链接标题页中获取结果到一个回调中
- c# - 如何使用 ExcelDataReader.Dataset 从 Excel 工作表中获取命名范围
- haskell - 使用幻像参数强制类型类实例
- java - 集群模式下的 Redis Pfcount
- javascript - 移动相机并在三个js中更新它的orbitControl
- jwt - 如何在 Postman 上打开 JWT 令牌以将声明值之一放在变量上
- bash - Linux:关闭 ssh 会话时结束运行 bash 脚本
- testing - CakePHP3:集成测试中的模拟方法?
- java - eclipse java photon中的INSTALL_PARSE_FAILED_NO_CERTIFICATES
- antd - blur 和 focusIn 的输入验证消息切换