[.NET] : CastingEnumerable

前言 :

写程序难免,会遇到要使用自定义函式来作对象数组转型。
写了一个对象来做这个动作,跟大家分享。

说明 :

这个对象的特点为:
1. 使用到才转型。不会在内存,建立整个转型后的数组副本。
2. 可在转型时加入参数。

使用范例 :

namespace CLK.Collections.ConsoleApplication
{
    public class User
    {
        public string LastName = string.Empty;

        public string FirstName = string.Empty;
    }

    public class Data
    {
        public string DisplayName = string.Empty;
    }

    class Program
    {
        static void Main(string[] args)
        {            
            User[] userArray = new User[2];

            userArray[0] = new User();
            userArray[0].LastName = "Chou";
            userArray[0].FirstName = "Clark";

            userArray[1] = new User();
            userArray[1].LastName = "AAAA";
            userArray[1].FirstName = "BBBBB";


            IEnumerable<Data> dataList = CreateDataList(userArray, "★★★★★");
            foreach (Data data in dataList)
            {
                Console.WriteLine(data.DisplayName);
            }
            Console.WriteLine("");
            

            Console.WriteLine("End");
            Console.ReadLine();
        }

        static IEnumerable<Data> CreateDataList(IEnumerable<User> userList, string decorator)
        {
            return new CastingEnumerable<Data, User>(userList, delegate(User user) { return CreateData(user, decorator); });
        }

        static Data CreateData(User user, string decorator)
        {
            Data data = new Data();
            data.DisplayName = decorator + user.LastName + "." + user.FirstName + decorator;
            return data;
        }
    }  
}

程序代码 :

namespace CLK.Collections
{
    public class CastingEnumerable<TResult, TSource> : IEnumerable<TResult>
    {
        //Properties 
        private readonly IEnumerable<TSource> _sourceEnumerable;

        private CastingEnumerableDelegate<TResult, TSource> _enumerableDelegate;


        // Construction 
        public CastingEnumerable(IEnumerable<TSource> sourceEnumerable, CastingEnumerableDelegate<TResult, TSource> enumerableDelegate)
        {
            Require#region Require

            if (sourceEnumerable == null) throw new ArgumentNullException();
            if (enumerableDelegate == null) throw new ArgumentNullException();

            #endregion
            _sourceEnumerable = sourceEnumerable;
            _enumerableDelegate = enumerableDelegate;
        }


        // Member 
        public IEnumerator<TResult> GetEnumerator()
        {
            return new CastingEnumerator<TResult, TSource>(_sourceEnumerable.GetEnumerator(), _enumerableDelegate);
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
}
namespace CLK.Collections
{
    public class CastingEnumerator<TResult, TSource> : IEnumerator<TResult>
    {
        //Properties 
        private readonly IEnumerator<TSource> _sourceEnumerator;

        private readonly CastingEnumerableDelegate<TResult, TSource> _enumerableDelegate;

        private TResult _currentResult = default(TResult);


        // Construction 
        public CastingEnumerator(IEnumerator<TSource> sourceEnumerator, CastingEnumerableDelegate<TResult, TSource> enumerableDelegate)
        {
            Require#region Require

            if (sourceEnumerator == null) throw new ArgumentNullException();
            if (enumerableDelegate == null) throw new ArgumentNullException();

            #endregion
            _sourceEnumerator = sourceEnumerator;
            _enumerableDelegate = enumerableDelegate;
        }

        public virtual void Dispose()
        {
            _sourceEnumerator.Dispose();
            _currentResult = default(TResult);
        }


        // Member  
        public TResult Current
        {
            get
            {
                return _currentResult;
            }
        }

        object System.Collections.IEnumerator.Current
        {
            get
            {
                return this.Current;
            }
        }

        public bool MoveNext()
        {
            if (_sourceEnumerator.MoveNext() == true)
            {
                _currentResult = _enumerableDelegate(_sourceEnumerator.Current);
                return true;
            }
            return false;
        }

        public void Reset()
        {
            _sourceEnumerator.Reset();
            _currentResult = default(TResult);
        }
    }
}
public delegate TResult CastingEnumerableDelegate<TResult, TSource>(TSource source);

相关资料 :

http://stackoverflow.com/questions/504729/how-do-i-cast-a-listt-effectively
http://msdn.microsoft.com/zh-tw/library/0yw3tz5k.aspx

原文地址:https://www.cnblogs.com/clark159/p/2205028.html