Есть много вещей, которые не так с вашим кодом, и мы можем разобраться с ними позже. Но давайте сначала ответим на ваши вопросы. Я буду немного буквальным и прямым, так как я не могу предположить, почему вы сделали это так, как это делается.
почему метод расширения не возвращает измененный узел в операциях вставки.
Поскольку ваш метод ничего не возвращает
Но это работало отлично во время создания связанного списка.
Да, поскольку этот код никогда не изменяет параметр 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
как linkedList
, CreateLinkedList
как AppendNode
и InsertNode
как 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);
}
}