C# 将 "Current" 属性 添加到继承自列表 <T> 的列表 class
C# Adding "Current" property to a list class inheriting from list<T>
我想将“当前”属性 添加到我的列表 class VolumeList。
这是我的代码:
class Volume
{
private string name;
private string color;
private bool has_segment;
public Volume(string Name, string color, bool has_segment)
this.name = name;
this.color = color;
this.has_segment = has_segment;
public string Name
{
get { return name; }
set { name = value; }
}
public string Color
{
get { return color; }
set { color = value; }
}
public bool HasSegment
{
get { return has_segment; }
set { has_segment = value; }
}
public static ROOTList<Volume> VolumeList{ get; set; } = new ROOTList<Volume>();
}
public class ROOTList<T> : List<T>
{
public T Last
{
get
{
return this[this.Count - 1];
}
set
{
this[this.Count - 1] = value;
}
}
public T First
{
get
{
return this[0];
}
set
{
this[0] = value;
}
}
public T Current
{
}
}
我想添加“当前”property/method 以便像这样使用它:
Volume.VolumeList.Current.Name (I get the name of the current volume)
Volume.VolumeList.Current.Name = "test" (I set the name "test" to the current volume).
First
和“Last` 方法有效。
请问有什么解决办法吗?
此致
关于如何执行此操作有几个选项。由于您刚刚开始,我会说使用选项 1,因为这要简单得多。
选项 1:基本使用 LINQ
下面是 Volume
class 和 Main
方法,显示了用法示例。您可以使用 Linq 获取卷列表中的 first/last 项目,然后您可以使用 volumes[i]
设置列表中各个项目的属性,其中 i
是项目的索引列表。
您还可以使用 Linq 根据 Color
、Name
、HasVolume
查找特定卷,然后使用 foreach
循环更改每个卷的属性。
此处提供有关 LINQ 的更多信息:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/。
看看下面的例子:
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
var volumes = new List<Volume>();
var volume1 = new Volume("vol1", "red", true);
var volume2 = new Volume("vol2", "red", true);
volumes.Add(volume1); //adds the first volume
volumes.Add(volume2); //adds the second volume
var lastVolume = volumes.First(); //gets the first volume
var firstVolume = volumes.Last(); //gets the last volume
volumes[0].Color = "blue"; //sets the first volume color to blue
volumes[1].Color = "green"; //sets the second volume color to green
// set all green volumes to purple
var greenVolumes = volumes.Where(v => v.Color == "green");
foreach (var greenVolume in greenVolumes)
{
greenVolume.Color = "purple";
}
}
}
public class Volume
{
public string Name { get; set; }
public string Color { get; set; }
public bool HasSegment { get; set; }
public Volume(string name, string color, bool hasSegment)
{
Name = name;
Color = color;
HasSegment = hasSegment;
}
}
}
选项 2:使用迭代器模式更高级
在这里查看迭代器模式:https://www.dofactory.com/net/iterator-design-pattern。
基本上,您可以通过选择 MoveNext()
、Last
、First
和 Current
逐步浏览列表。我添加了一个 _current
字段来跟踪您正在使用的项目。它涉及到collection/list.
的索引
using System.Collections.Generic;
namespace WebApplication1.Sandbox
{
public class Volume
{
public string Name { get; set; }
public string Color { get; set; }
public bool HasSegment { get; set; }
public Volume(string name, string color, bool hasSegment)
{
Name = name;
Color = color;
HasSegment = hasSegment;
}
}
public class Iterator<T>
{
private readonly List<T> _items;
private int _index;
public T Last
{
get => _items[_items.Count - 1];
set => _items[_items.Count - 1] = value;
}
public T First
{
get => _items[0];
set => _items[0] = value;
}
public T Current
{
get => _items[_index];
set => _items[_index] = value;
}
public Iterator(List<T> items)
{
_items = items;
}
public bool MoveNext()
{
if (_index == _items.Count - 1)
{
return false;
}
else
{
_index++;
return true;
}
}
}
}
现在你可以像在这个单元测试中一样使用它了:
[Fact]
public void VolumeIteratorGetsNextThenSetsCurrentByProperty()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
sut.Current.Name = "vol2modifiedAgain";
Assert.Equal("vol2modifiedAgain", sut.Current.Name);
}
单元测试在这里:
using System.Collections.Generic;
using WebApplication1.Sandbox;
using Xunit;
namespace WebApplication1.Tests
{
public class VolumeIteratorTests
{
private List<Volume> _volumes => new List<Volume>()
{
new Volume("vol1", "green", true),
new Volume("vol2", "green", true)
};
[Fact]
public void VolumeIteratorGetsCurrent()
{
var sut = new Iterator<Volume>(_volumes);
Assert.Equal("vol1", sut.Current.Name);
}
[Fact]
public void VolumeIteratorGetsNext()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
Assert.Equal("vol2", sut.Current.Name);
}
[Fact]
public void VolumeIteratorGetsNextThenSetsCurrent()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
sut.Current = new Volume("vol2modified", "green", false);
Assert.Equal("vol2modified", sut.Current.Name);
}
[Fact]
public void VolumeIteratorGetsNextThenSetsCurrentByProperty()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
sut.Current.Name = "vol2modifiedAgain";
Assert.Equal("vol2modifiedAgain", sut.Current.Name);
}
[Fact]
public void VolumeIteratorGetsLast()
{
var sut = new Iterator<Volume>(_volumes);
Assert.Equal("vol2", sut.Last.Name);
}
[Fact]
public void VolumeIteratorSetsLast()
{
var sut = new Iterator<Volume>(_volumes);
sut.Last = new Volume("last", "red", true);
Assert.Equal("last", sut.Last.Name);
}
[Fact]
public void VolumeIteratorGetsFirst()
{
var sut = new Iterator<Volume>(_volumes);
Assert.Equal("vol1", sut.First.Name);
}
[Fact]
public void VolumeIteratorSetsFirst()
{
var sut = new Iterator<Volume>(_volumes);
sut.First = new Volume("first", "red", true);
Assert.Equal("first", sut.First.Name);
}
[Fact]
public void MoveNextReturnsTrueIfNotLastItem()
{
var sut = new Iterator<Volume>(_volumes);
Assert.True(sut.MoveNext());
}
[Fact]
public void MoveNextReturnsFalseIfLastItem()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
Assert.False(sut.MoveNext());
}
}
}
我想将“当前”属性 添加到我的列表 class VolumeList。 这是我的代码:
class Volume
{
private string name;
private string color;
private bool has_segment;
public Volume(string Name, string color, bool has_segment)
this.name = name;
this.color = color;
this.has_segment = has_segment;
public string Name
{
get { return name; }
set { name = value; }
}
public string Color
{
get { return color; }
set { color = value; }
}
public bool HasSegment
{
get { return has_segment; }
set { has_segment = value; }
}
public static ROOTList<Volume> VolumeList{ get; set; } = new ROOTList<Volume>();
}
public class ROOTList<T> : List<T>
{
public T Last
{
get
{
return this[this.Count - 1];
}
set
{
this[this.Count - 1] = value;
}
}
public T First
{
get
{
return this[0];
}
set
{
this[0] = value;
}
}
public T Current
{
}
}
我想添加“当前”property/method 以便像这样使用它:
Volume.VolumeList.Current.Name (I get the name of the current volume)
Volume.VolumeList.Current.Name = "test" (I set the name "test" to the current volume).
First
和“Last` 方法有效。
请问有什么解决办法吗?
此致
关于如何执行此操作有几个选项。由于您刚刚开始,我会说使用选项 1,因为这要简单得多。
选项 1:基本使用 LINQ
下面是 Volume
class 和 Main
方法,显示了用法示例。您可以使用 Linq 获取卷列表中的 first/last 项目,然后您可以使用 volumes[i]
设置列表中各个项目的属性,其中 i
是项目的索引列表。
您还可以使用 Linq 根据 Color
、Name
、HasVolume
查找特定卷,然后使用 foreach
循环更改每个卷的属性。
此处提供有关 LINQ 的更多信息:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/。
看看下面的例子:
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
var volumes = new List<Volume>();
var volume1 = new Volume("vol1", "red", true);
var volume2 = new Volume("vol2", "red", true);
volumes.Add(volume1); //adds the first volume
volumes.Add(volume2); //adds the second volume
var lastVolume = volumes.First(); //gets the first volume
var firstVolume = volumes.Last(); //gets the last volume
volumes[0].Color = "blue"; //sets the first volume color to blue
volumes[1].Color = "green"; //sets the second volume color to green
// set all green volumes to purple
var greenVolumes = volumes.Where(v => v.Color == "green");
foreach (var greenVolume in greenVolumes)
{
greenVolume.Color = "purple";
}
}
}
public class Volume
{
public string Name { get; set; }
public string Color { get; set; }
public bool HasSegment { get; set; }
public Volume(string name, string color, bool hasSegment)
{
Name = name;
Color = color;
HasSegment = hasSegment;
}
}
}
选项 2:使用迭代器模式更高级
在这里查看迭代器模式:https://www.dofactory.com/net/iterator-design-pattern。
基本上,您可以通过选择 MoveNext()
、Last
、First
和 Current
逐步浏览列表。我添加了一个 _current
字段来跟踪您正在使用的项目。它涉及到collection/list.
using System.Collections.Generic;
namespace WebApplication1.Sandbox
{
public class Volume
{
public string Name { get; set; }
public string Color { get; set; }
public bool HasSegment { get; set; }
public Volume(string name, string color, bool hasSegment)
{
Name = name;
Color = color;
HasSegment = hasSegment;
}
}
public class Iterator<T>
{
private readonly List<T> _items;
private int _index;
public T Last
{
get => _items[_items.Count - 1];
set => _items[_items.Count - 1] = value;
}
public T First
{
get => _items[0];
set => _items[0] = value;
}
public T Current
{
get => _items[_index];
set => _items[_index] = value;
}
public Iterator(List<T> items)
{
_items = items;
}
public bool MoveNext()
{
if (_index == _items.Count - 1)
{
return false;
}
else
{
_index++;
return true;
}
}
}
}
现在你可以像在这个单元测试中一样使用它了:
[Fact]
public void VolumeIteratorGetsNextThenSetsCurrentByProperty()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
sut.Current.Name = "vol2modifiedAgain";
Assert.Equal("vol2modifiedAgain", sut.Current.Name);
}
单元测试在这里:
using System.Collections.Generic;
using WebApplication1.Sandbox;
using Xunit;
namespace WebApplication1.Tests
{
public class VolumeIteratorTests
{
private List<Volume> _volumes => new List<Volume>()
{
new Volume("vol1", "green", true),
new Volume("vol2", "green", true)
};
[Fact]
public void VolumeIteratorGetsCurrent()
{
var sut = new Iterator<Volume>(_volumes);
Assert.Equal("vol1", sut.Current.Name);
}
[Fact]
public void VolumeIteratorGetsNext()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
Assert.Equal("vol2", sut.Current.Name);
}
[Fact]
public void VolumeIteratorGetsNextThenSetsCurrent()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
sut.Current = new Volume("vol2modified", "green", false);
Assert.Equal("vol2modified", sut.Current.Name);
}
[Fact]
public void VolumeIteratorGetsNextThenSetsCurrentByProperty()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
sut.Current.Name = "vol2modifiedAgain";
Assert.Equal("vol2modifiedAgain", sut.Current.Name);
}
[Fact]
public void VolumeIteratorGetsLast()
{
var sut = new Iterator<Volume>(_volumes);
Assert.Equal("vol2", sut.Last.Name);
}
[Fact]
public void VolumeIteratorSetsLast()
{
var sut = new Iterator<Volume>(_volumes);
sut.Last = new Volume("last", "red", true);
Assert.Equal("last", sut.Last.Name);
}
[Fact]
public void VolumeIteratorGetsFirst()
{
var sut = new Iterator<Volume>(_volumes);
Assert.Equal("vol1", sut.First.Name);
}
[Fact]
public void VolumeIteratorSetsFirst()
{
var sut = new Iterator<Volume>(_volumes);
sut.First = new Volume("first", "red", true);
Assert.Equal("first", sut.First.Name);
}
[Fact]
public void MoveNextReturnsTrueIfNotLastItem()
{
var sut = new Iterator<Volume>(_volumes);
Assert.True(sut.MoveNext());
}
[Fact]
public void MoveNextReturnsFalseIfLastItem()
{
var sut = new Iterator<Volume>(_volumes);
sut.MoveNext();
Assert.False(sut.MoveNext());
}
}
}