zoukankan      html  css  js  c++  java
  • [原创]使用接口还是使用抽象类?

    在使用C#的时候,经常会用到集合,惯用的做法是实例化一个List或Collection,然后存放东西就行了。我总是很懒,所以把Collection封装了一下,加了个锁,可以线程安全的访问了。

    这位看官说了:你说的是集合,跟你的标题扯不上关系吧?

    是的,到目前为止是的。然而,当我们遇到这样的问题时:N多个类有相同的属性或方法。这个时候你第一想到的是接口。没错,接口可以很好的表述你的要求。但我要说,请稍等。

    你可以使用接口,那么为什么不试试抽象类呢?

    定义一个接口,其所有的属性与方法,你都要在实现类中全部重现。

    使用抽象类,在抽象基类里可以实现一些属性或方法,子类只需要重载特殊的属性或方法即可。

    不管从实用性还是代码简洁性,抽象类,在我看来是首选。

    这也是我不同意下面一个帖子里使用接口的原因。

    C# 泛型类型必须继承接口的问题

    好了,下面放一个我自己写的泛型抽象基类,其使用方法见

    原创 C# 正则表达式 读写 Ini 文件

    namespace goldli.Utility.Library
    {
        /// <summary>
        /// 泛型集合类,子元素拥有默认new构造函数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public abstract class Collection<T> : CollectionBase //where T : class ,new()
        {
            /// <summary>
            /// 泛型是否默认值
            /// 对泛型实例与默认值比较使用 Equals
            /// </summary>
            /// <param name="item"></param>
            /// <returns></returns>
            public bool IsDefault(T item)
            {
                return Equals(item, default(T));
            }
     
            /// <summary>
            /// 添加,item可以为null,方便大量添加后赋值
            /// </summary>
            /// <param name="item"></param>
            public void Add(T item)
            {
                Lock();
                try
                {
                    List.Add(item);
                    Selected = item;//同时选中
                }
                finally
                {
                    UnLock();
                }
            }
     
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="item"></param>
            public void Remove(T item)
            {
                var tmp = Find(item);
                if (IsDefault(tmp)) throw new ArgumentNullException("type " + typeof(T).Name + " is null.");
                Lock();
                try
                {
                    List.Remove(tmp);
                }
                finally
                {
                    UnLock();
                }
            }
     
            public T this[int index]
            {
                get
                {
                    Lock();
                    T result;
                    try
                    {
                        result = (0 <= index) && (index < Count) ? (T)InnerList[index] : default(T);
                    }
                    finally
                    {
                        UnLock();
                    }
                    return result;
                }
            }
     
            /// <summary>
            /// 查找
            /// </summary>
            /// <param name="value"></param>
            /// <returns></returns>
            public abstract T Find(object value);
     
            /// <summary>
            /// 选择的某个item
            /// </summary>
            public T Selected { getset; }
     
            #region 线程安全
     
            /// <summary>
            /// 上锁
            /// </summary>
            public void Lock()
            {
                Monitor.Enter(List);
            }
     
            /// <summary>
            /// 解锁
            /// </summary>
            public void UnLock()
            {
                Monitor.Exit(List);
            }
     
            #endregion
     
            /// <summary>
            /// 公开IList
            /// </summary>
            public new IList List { get { return base.List; } }
        }
    }
    
  • 相关阅读:
    C/C++内存管理 笔记
    RAII惯用法:C++资源管理的利器
    JS、Flash 实现复制功能 (浏览器兼容)
    JS页面刷新实现方法总结
    php 一些常用的语句
    使用ZeroClipboard解决跨浏览器复制到剪贴板的问题
    window.opener.location.reload() and href()的区别 弹出页修改后刷新父窗体
    查看Mysql数据库大小
    JQUERY操作集锦
    十进制正整数转换成六十二进制
  • 原文地址:https://www.cnblogs.com/goldli/p/3374958.html
Copyright © 2011-2022 走看看