C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

--/--/-- --:--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
タグ:
トラックバック(-) | コメント(-) | このエントリーを含むはてなブックマーク
2010/07/15 23:13
適当に書いたので注意

using System;
using System.Dynamic;
using System.Reflection;

namespace MoroMoro.Dynamic
{
    public sealed class MemberAdapter : DynamicObject
    {
        private static BindingFlags GetBindingFlags(bool ignoreCase)
        {
            var baseFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
            return (ignoreCase ? (baseFlags | BindingFlags.IgnoreCase) : baseFlags);
        }

        public MemberAdapter(object target)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            this._target = target;
        }

        private readonly object _target;

        private Type TargetType
        {
            get
            {
                return this._target.GetType();
            }
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var flags = GetBindingFlags(binder.IgnoreCase);
            var field = TargetType.GetField(binder.Name, flags);
            var property = TargetType.GetProperty(binder.Name, flags);

            if (field != null)
            {
                result = field.GetValue(this._target);
                return true;
            }
            else if ((property != null) && (property.CanRead))
            {
                result = property.GetValue(this._target, null);
                return true;
            }
            else
            {
                result = null;
                return false;
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            var flags = GetBindingFlags(binder.IgnoreCase);
            var field = TargetType.GetField(binder.Name, flags);
            var property = TargetType.GetProperty(binder.Name, flags);

            if (field != null)
            {
                field.SetValue(this._target, value);
                return true;
            }
            else if ((property != null) && (property.CanRead))
            {
                property.SetValue(this._target, value, null);
                return true;
            }
            else
            {
                return false;
            }
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            var flags = GetBindingFlags(binder.IgnoreCase);
            var filter = (MemberFilter)((member, c) =>
            {
                var memberAsMethod = member as MethodInfo;
                if (memberAsMethod == null)
                {
                    return false;
                }
                if (!string.Equals(memberAsMethod.Name, binder.Name, (binder.IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)))
                {
                    return false;
                }
                var parameters = memberAsMethod.GetParameters();
                if (args.Length != parameters.Length)
                {
                    return false;
                }
                for (var i = 0; i < parameters.Length; i++)
                {
                    var parameter = parameters[i];
                    var arg = args[i];
                    if (arg == null)
                    {
                        continue;
                    }
                    if (parameter.ParameterType.IsAssignableFrom(arg.GetType()))
                    {
                        continue;
                    }
                    return false;
                }
                return true;
            });
            var methods = TargetType.FindMembers(MemberTypes.Method, flags, filter, null);
            if ((methods == null) || (methods.Length == 0))
            {
                result = null;
                return false;
            }

            var method = (MethodInfo)methods[0];
            result = method.Invoke(this._target, args);
            return true;
        }
    }
}



サンプル
class Program
{
    class Sample
    {
        public Sample()
        {
            this._i = 0;
        }

        private readonly int _i;

        private void Method1()
        {
            Console.WriteLine(_i);
        }
    }

    static void Main()
    {
        var s = new Sample();
        dynamic m = new MemberAdapter(s);
        m._i++;
        m.Method1();

        Console.ReadKey();
    }
}



スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。