`

唯一元素List UniqueList

阅读更多
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection.Emit;
using NUnit.Framework;

namespace SASTest
{

    
#region 唯一列表
    
//添加元素保证唯一
    
//修改元素保证唯一
    public class UniqueList<T> : IList<T>
        
where T : UniqueList<T>.UniqueItem
    {
        List
<T> list = new List<T>();

        
public int Count
        {
            
get
            {
                
return list.Count;
            }
        }

        
public int Add(T item)
        {
            
if (!Contains(item, false))
            {
                list.Add(item);
                item.CheckerEvent 
+= new CallUniqueCheck(Item_CheckerEvent);
            }
            
else
            {
                
throw new NotUniqueException();
            }
            
return list.Count - 1;
        }

        
public T this[int index]
        {
            
get
            {
                
return list[index];
            }
            
set
            {
                
if (value == null)
                    
throw new NullReferenceException();

                T tmp 
= list[index];//备份原来的对象
                list[index] = value;//修改集合中的元素

                
if (Contains(value, true))//修改结束判断是否有重复
                {
                    list[index] 
= tmp;//如果有重复,恢复集合
                    throw new NotUniqueException();//抛出异常
                }

                
if (!object.ReferenceEquals(tmp, value))//如果没有重复并且替换后的元素和原来的元素不是同一个对象,要为该元素添加属性修改检查事件
                    value.CheckerEvent += new CallUniqueCheck(Item_CheckerEvent);

            }
        }

        
private void Item_CheckerEvent(T item, Action<T> action)
        {
            T tmp 
= (T)Activator.CreateInstance(typeof(T));
            Copy(item, tmp);
//备份原来的属性值到临时对象上
            action(item);
            
if (Contains(item, true))
            {
                Copy(tmp, item);
//如果失败,将备份的信息恢复
                throw new NotUniqueException();
            }
        }

        
private bool Contains(T item, bool edit)//检查修改后的集合是否有重复 , 对于添加元素,在添加前检查是否已经有一个同样的。如果是修改, 则先修改再看修改后是否有两个相同的元素。
        {                                       //修改后检查,如果发现有重复,一定要恢复原来的集合
            bool result = false;
            
if (item == null)
                
throw new NullReferenceException();

            
int count = 0;
            
foreach (T ui in list)
            {
                
if (ui.Equals(item))
                {
                    count
++;
                }
            }
            
if (count <= 0)
                result 
= false;
            
else if (count > 0)
            {
                result 
= true;
                
if (edit && count == 1)
                    result 
= false;

            }
            
return result;
        }

        
private static void Copy(T source, T target)//辅助方法,拷备属性
        {
            Type t 
= typeof(T);

            
foreach (var item in t.GetProperties())
            {
                
try
                {
                    item.SetValue(target, item.GetValue(source, 
null), null);
                }
                
catch (Exception)
                {
                }
            }
        }

        
public delegate void CallUniqueCheck(T item, Action<T> action);

        
public abstract class UniqueItem
        {
            
internal event UniqueList<T>.CallUniqueCheck CheckerEvent;

            
public void TryPropertyChange(Action<T> action)
            {
                
if (CheckerEvent != null)
                {
                    CheckerEvent((T)
this, action);
                }
                
else//如果是为空表明现在这个对象还没有添加到集合中
                {
                    action((T)
this);//直接修改属性
                }
            }

        }

        
#region IList<T> 成员

        
public int IndexOf(T item)
        {
            
return list.IndexOf(item);
        }

        
public void Insert(int index, T item)
        {
            
if (!Contains(item, false))
            {
                list.Insert(index, item);
                item.CheckerEvent 
+= new CallUniqueCheck(Item_CheckerEvent);
            }
            
else
            {
                
throw new NotUniqueException();
            }
        }

        
public void RemoveAt(int index)
        {
            list.RemoveAt(index);
        }

        
#endregion

        
#region ICollection<T> 成员

        
void ICollection<T>.Add(T item)
        {
            
this.Add(item);
        }

        
public void Clear()
        {
            
this.list.Clear();
        }

        
public bool Contains(T item)
        {
            
return this.list.Contains(item);
        }

        
public void CopyTo(T[] array, int arrayIndex)
        {
            
this.list.CopyTo(array, arrayIndex);
        }

        
public bool IsReadOnly
        {
            
get
            {
                
return false;
            }
        }

        
public bool Remove(T item)
        {
            
return list.Remove(item);
        }

        
#endregion

        
#region IEnumerable<T> 成员

        
public IEnumerator<T> GetEnumerator()
        {
            
return list.GetEnumerator();
        }

        
#endregion

        
#region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            
return list.GetEnumerator();
        }

        
#endregion
    }



    
public class NotUniqueException : ApplicationException
    {
        
public NotUniqueException()
            : 
base("元素重复")
        {

        }
        
public NotUniqueException(string message)
            : 
base(message)
        {

        }
    }

    
#endregion

    
#region 测试代码
    [TestFixture]
    
public class Tester
    {
        [Test]
        [ExpectedException(
"SASTest.NotUniqueException")]
        
public void AddTest()//添加相同元素 
        {

            UniqueList
<MyPoint> list = new UniqueList<MyPoint>();

            list.Add(
new MyPoint { X = 1, Y = 1 });
            list.Add(
new MyPoint { X = 1, Y = 2 });
            list.Add(
new MyPoint { X = 2, Y = 1 });
            list.Add(
new MyPoint { X = 1, Y = 1 });


            Assert.AreEqual(
3, list.Count);//冲突时添不进相同元素
        }

        [Test]
        [ExpectedException(
"SASTest.NotUniqueException")]
        
public void UpdatePropertyTest()//修改元素属性,使元素重复
        {
            UniqueList
<MyPoint> list = new UniqueList<MyPoint>();
            list.Add(
new MyPoint { X = 1, Y = 1 });
            list.Add(
new MyPoint { X = 1, Y = 2 });
            list.Add(
new MyPoint { X = 2, Y = 1 });

            list[
0].X = 2;

            Assert.AreEqual(
1, list[0].X);//冲突时修改不了

            list[
0].X = 10;
            Assert.AreEqual(
10, list[0].X);//不冲突时可以修改
        }

        [Test]
        [ExpectedException(
"SASTest.NotUniqueException")]
        
public void UpdateTest()//修改集合元素,使元素重复
        {
            UniqueList
<MyPoint> list = new UniqueList<MyPoint>();
            list.Add(
new MyPoint { X = 1, Y = 1 });
            list.Add(
new MyPoint { X = 1, Y = 2 });
            list.Add(
new MyPoint { X = 2, Y = 1 });

            list[
0= new MyPoint { X = 1, Y = 2 };

            Assert.AreEqual(
2, list[0].Y);

            list[
0= new MyPoint { X = 10, Y = 10 };

            Assert.AreEqual(
10, list[0].X);
            Assert.AreEqual(
10, list[0].Y);
        }

    }

    
public class MyPoint : UniqueList<MyPoint>.UniqueItem
    {
        
private int _x;

        
public int X
        {
            
get { return _x; }
            
set
            {
                TryPropertyChange(p 
=> p._x = value);
            }
        }

        
private int _y;

        
public int Y
        {
            
get { return _y; }
            
set
            {
                TryPropertyChange(p 
=> p._y = value);
            }
        }

        
public override bool Equals(object obj)
        {
            
if (obj == null)
                
throw new NullReferenceException();
            MyPoint point 
= obj as MyPoint;
            
return this.X.Equals(point.X) && this.Y.Equals(point.Y);
        }
    }

    
#endregion
}
分享到:
评论

相关推荐

    数组,List 重复元素统计数量,找出唯一的元素

    int[] arr = { 1, 2, 2, 3, 3, 4, 4, 4, 1, 5, 6, 6, 6 }; 两种不同方式(使用map和list两种方式)获得一下输出结果 数组和list 可以使用相同的方法,自己测试可以 控制台输出 ...数组中唯一的元素是:5

    C#遍历List并删除某个元素的方法

    当我们需要遍历List并根据条件删除特定元素时,需要注意正确的方法,以避免在遍历过程中出现错误。以下将详细介绍如何在C#中遍历List并删除元素,包括正序和倒序遍历的技巧。 首先,我们来看一下错误的遍历方式。...

    std::List类的遍历获得元素的操作二法

    由于`std::list`不是随机访问容器,因此它不支持像数组那样的通过索引直接访问元素(如`[]`运算符)。但是,`std::list`提供了迭代器接口,我们可以利用迭代器来遍历并访问容器中的每个元素。以下是两种遍历`std::...

    list 元素循环比较

    list 元素循环比较list 元素循环比较list 元素循环比较list 元素循环比较list 元素循环比较list 元素循环比较

    java获取list中两元素时间差

    Java 获取 List 中两元素时间差 Java 中获取 List 中两元素时间差是指在 List 集合中计算每个元素之间的时间差异。下面是相关知识点的详细解释: List 数据结构 List 是一种常见的数据结构,在 Java 中有多种实现...

    List列表拒绝添加重复信息

    这个自定义的`UniqueList`类会在尝试添加元素时先检查它是否已经在列表中,只有当元素未出现过时,才会执行`list.append()`。 总之,Python提供了多种方法来处理不允许添加重复信息的List,如使用Set、OrderedDict...

    python 寻找list中最大元素对应的索引方法

    以上这篇python 寻找list中最大元素对应的索引方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持软件开发网。 您可能感兴趣的文章:python numpy和list查询其中某个数的个数及定位方法...

    STL中list的使用

    ` 创建包含三个元素的`list`,但所有元素默认为0。 3. **特定值list**:`list&lt;int&gt; c2(5, 2);` 创建包含五个元素的`list`,所有元素值为2。 4. **复制list**:`list&lt;int&gt; c4(c2);` 创建一个`list`,它是`c2`的副本。...

    使用python list 查找所有匹配元素的位置实例

    如下所示: import re word = test s = test abcdas test 1234 testcase testsuite ... 您可能感兴趣的文章:Python 查找list中的某个元素的所有的下标方法python 获取list特定元素下标的实例讲解python

    CSharp_List.zip_C# list_C#中list_C#中list的用法_C#怎么引用List_c# list

    `List&lt;T&gt;`会自动扩容以适应更多的元素,但可以通过设置`Capacity`属性来手动设置容量。当列表的大小超过容量时,会自动进行扩容。同样,如果列表元素减少,容量过大时,也会自动缩小容量。 以上就是C#中`List&lt;T&gt;`的...

    list to list 将list内容移到另一个list

    `list to list` 操作通常指的是将一个列表(list)的内容移动到另一个列表中,这可能涉及到列表的复制、合并或者元素的迁移。下面我们将深入探讨这个主题,同时也会关注到`listtolist.js`这个文件,它可能是...

    【Robotframework】列表List的常用操作.pdf

    如 `List Should Contain Sub List ${list} ${sublist}` 确保主列表包含子列表的所有元素。 6. **List Should Not Contain Duplicates**: 判断列表中是否存在重复元素。在去重后,使用此关键字确认列表不含重复元素...

    java计算同一个list中是否有相同的值

    在 Java 编程中,判断一个 `List` 中是否存在重复元素是一项常见的需求。特别是在数据处理、验证或分析等场景中,确保数据的唯一性对于维持数据完整性至关重要。 #### 核心概念解析 在给定的代码片段中,作者提供...

    C#查找列表中所有重复出现元素的方法

    `List&lt;T&gt;`是.NET框架提供的一个泛型类,它实现了`IList&lt;T&gt;`、`ICollection&lt;T&gt;`和`IEnumerable&lt;T&gt;`接口,提供了动态数组的功能,允许我们方便地添加、删除和查找元素。对于查找重复元素,我们通常会遍历列表,比较每...

    在list集合中输入元素,去除重复的元素并输出

    根据给定文件的信息,本文将详细介绍如何在Java的List集合中去除重复元素的三种方法:使用for循环、使用迭代器以及利用HashSet的特性。 ### 一、使用for循环去除重复元素 这种方法的基本思想是通过双重循环来遍历...

    java的list取之方法

    `List`的主要特点是可以通过索引访问元素,同时也支持插入、删除等操作。 ### List的主要实现类 1. **ArrayList**:基于动态数组实现,线程不安全,但提供了高效的随机访问能力。 2. **LinkedList**:基于双向链表...

    Python 查看list中是否含有某元素的方法

    用关键字 in 和not in 来 ... 您可能感兴趣的文章:python list是否包含另一个list所有元素的实例Python判断两个list是否是父子集关系的实例python对list中的每个元素进行某种操作的方法Python之list对应元素求和的方法

    Scala的List类方法整合

    ### Scala的List类方法整合 在Scala编程语言中,`List` 类是处理有序集合的一种常见方式。本文将详细介绍 `List` 类中的多种方法及其用途,帮助开发者更好地理解和使用这些功能。 #### 1. `def + (elem: A): List...

    list嵌套list例子

    在Python编程语言中,列表(list)是一种非常重要的数据结构,它可以存储任意类型的对象,包括数字、字符串,甚至是其他列表。当我们谈论“list嵌套list”时,这意味着在一个列表内部包含了一个或多个列表,这样的...

Global site tag (gtag.js) - Google Analytics