Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [ClassInterface(ClassInterfaceType.AutoDispatch)]
- [ComVisible(true)]
- [Guid("1521B4B2-F38B-4CAD-BB45-3C6E1F00982F")]
- public class AutoWrap : IReflect
- {
- protected internal object O = null;
- protected internal Type T = null;
- FieldInfo[] Поля = null;
- MemberInfo[] Мемберы = null;
- internal MethodInfo[] Методы = null;
- PropertyInfo[] Свойства = null;
- // Dictionary<string, FieldInfo> HashFieldInfo;
- BindingFlags staticBinding = BindingFlags.Public | BindingFlags.Static;
- internal bool ЭтоТип;
- internal bool ЭтоExpandoObject;
- public static bool ЭтоСемерка = false;
- public static bool ВыводитьСообщениеОбОшибке = true;
- public static Exception ПоследняяОшибка = null;
- public static Dictionary<string, bool> МетодыObject;
- static AutoWrap()
- {
- МетодыObject = new Dictionary<string, bool>();
- foreach (var метод in typeof(object).GetMethods(BindingFlags.Public | BindingFlags.Instance))
- МетодыObject[метод.Name] = true;
- }
- static Exception NotImplemented()
- {
- var method = new System.Diagnostics.StackTrace(true).GetFrame(1).GetMethod().Name;
- System.Diagnostics.Debug.Assert(false, method);
- return new NotImplementedException(method);
- }
- void ДобавитьМетодыObject()
- {
- }
- public static object ПолучитьРеальныйОбъект(object obj)
- {
- if (obj is AutoWrap)
- {
- return ((AutoWrap)obj).O;
- }
- return obj;
- }
- internal static object[] ПолучитьМассивРеальныхОбъектов(object[] args)
- {
- if (args.Length == 0)
- return args;
- object[] res = new object[args.Length];
- for (int i = 0; i < args.Length; i++)
- {
- res[i] = ПолучитьРеальныйОбъект(args[i]);
- }
- return res;
- }
- internal static void УстановитьИзмененияВМассиве(object[] ОригинальныйМассив, object[] МассивРеальныхОбъектов)
- {
- if (ОригинальныйМассив == МассивРеальныхОбъектов)
- return;
- for (int i = 0; i < ОригинальныйМассив.Length; i++)
- {
- object obj = ОригинальныйМассив[i];
- if (obj is AutoWrap)
- {
- AutoWrap элемент = (AutoWrap)obj;
- if (!object.Equals(элемент.O, МассивРеальныхОбъектов[i]))
- ОригинальныйМассив[i] = ОбернутьОбъект(МассивРеальныхОбъектов[i]);
- }
- else
- {
- if (!object.Equals(ОригинальныйМассив[i], МассивРеальныхОбъектов[i]))
- ОригинальныйМассив[i] = ОбернутьОбъект(МассивРеальныхОбъектов[i]);
- }
- }
- }
- public static object ОбернутьОбъект(object obj)
- {
- if (obj != null)
- {
- //switch (obj.GetType().ToString())
- //{
- // case "System.String":
- // case "System.DateTime":
- // case "System.Boolean":
- // case "System.Byte":
- // case "System.Char":
- // case "System.Decimal":
- // case "System.Double":
- // case "System.Single": // Float
- // case "System.Int32":
- // case "System.Int64": // Long
- // case "System.SByte":
- // case "System.Int16":// Short
- // case "System.UInt32":
- // case "System.UInt64":
- // case "System.UInt16":
- // break; // These Types do not get wrapped
- // default:
- // obj = new AutoWrap(obj); // Wrap Type
- // break;
- //}
- // Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single.
- Type Тип = obj.GetType();
- if (Тип==typeof(System.IntPtr) || Тип==typeof(System.UIntPtr))
- return new AutoWrap(obj);
- if (ЭтоСемерка)
- {
- if (Тип == typeof(System.Decimal)) return ((Decimal)obj).ToString(CultureInfo.InvariantCulture);
- if (Тип.IsPrimitive)
- {
- if ((Тип == typeof(System.Int64) || Тип == typeof(System.UInt32) || Тип == typeof(System.UInt64) || Тип == typeof(System.UInt16) || Тип == typeof(System.SByte)))
- obj = Convert.ChangeType(obj, typeof(string), CultureInfo.InvariantCulture);
- }
- else if (!(Тип == typeof(System.DateTime)
- || Тип == typeof(System.String)
- || Тип == typeof(System.Decimal)
- || Тип.IsCOMObject)
- )
- obj = new AutoWrap(obj);
- }
- else
- {
- if (Тип.IsArray)
- {
- Type ТипМассива = Тип.GetElementType();
- if (ТипМассива != null)
- Тип = ТипМассива;
- }
- if (!(Тип.IsPrimitive
- || Тип == typeof(System.Decimal)
- || Тип == typeof(System.DateTime)
- || Тип == typeof(System.String)
- || Тип.IsCOMObject)
- )
- obj = new AutoWrap(obj);
- }
- }
- return obj;
- }
- public AutoWrap(object obj)
- {
- O = obj;
- if (O is Type)
- {
- T = O as Type;
- ЭтоТип = true;
- }
- else
- {
- T = O.GetType();
- ЭтоТип = false;
- ЭтоExpandoObject = O is System.Dynamic.ExpandoObject;
- }
- }
- public AutoWrap(object obj, Type type)
- {
- O = obj;
- T = type;
- ЭтоТип = false;
- // ЭтоExpandoObject = O is System.Dynamic.ExpandoObject;
- }
- #region IReflect Members
- public System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
- {
- if (ЭтоТип)
- return T.GetField(name, staticBinding);
- else if (ЭтоExpandoObject)
- throw NotImplemented();
- else
- return T.GetField(name, bindingAttr);
- } /* SNIP other IReflect methods */
- public void ПроверитьНаДоступКПолям(ref System.Reflection.BindingFlags invokeAttr, int КоличествоПараметров)
- {
- if ((
- (
- (invokeAttr & BindingFlags.PutDispProperty) == BindingFlags.PutDispProperty)
- || (invokeAttr.HasFlag(System.Reflection.BindingFlags.PutRefDispProperty))
- )
- && (КоличествоПараметров == 1))
- {
- invokeAttr = invokeAttr | BindingFlags.SetField;
- }
- else if (((invokeAttr & BindingFlags.GetProperty) == BindingFlags.GetProperty) && (КоличествоПараметров == 0))
- {
- invokeAttr = invokeAttr | BindingFlags.GetField;
- }
- }
- public object InvokeMemberExpandoObject(string name, System.Reflection.BindingFlags invokeAttr, object[] args)
- {
- if (invokeAttr.HasFlag(BindingFlags.InvokeMethod))
- {
- return ((Delegate)((IDictionary<string, object>)((System.Dynamic.ExpandoObject)O))[name]).DynamicInvoke(args);
- }
- if (invokeAttr.HasFlag(BindingFlags.GetField))
- return ((IDictionary<string, object>)((System.Dynamic.ExpandoObject)O))[name];
- if (invokeAttr.HasFlag(BindingFlags.SetField))
- ((IDictionary<string, object>)((System.Dynamic.ExpandoObject)O))[name] = args[0];
- return null;
- }
- public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
- { // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)
- if (name == "[DISPID=-4]")
- {
- IEnumVARIANT rez = new EnumVariantImpl(((System.Collections.IEnumerable)O).GetEnumerator());
- return rez;
- }
- object[] args = ПолучитьМассивРеальныхОбъектов(argsOrig);
- culture = CultureInfo.InvariantCulture;
- // Invoke whatever needs be invoked!
- object obj;
- try
- {
- if (T.IsEnum && !((invokeAttr & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod))
- return ОбернутьОбъект(Enum.Parse(T, name));
- // if (ЭтоСемерка)
- ПроверитьНаДоступКПолям(ref invokeAttr, args.Length);
- if (ЭтоТип)
- obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
- else if (ЭтоExpandoObject)
- {
- if (invokeAttr.HasFlag(BindingFlags.InvokeMethod) && МетодыObject.ContainsKey(name))
- obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
- else
- obj = InvokeMemberExpandoObject(name, invokeAttr, args);
- }
- else
- obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
- }
- catch (Exception e)
- {
- ПоследняяОшибка = e;
- string Ошибка = "Ошибка в методе " + name + " " + e.Message + " " + e.Source;
- if (e.InnerException != null)
- Ошибка = Ошибка + "\r\n" + e.InnerException.ToString();
- if (ВыводитьСообщениеОбОшибке)
- {
- MessageBox.Show(Ошибка);
- MessageBox.Show(e.StackTrace);
- MessageBox.Show(invokeAttr.ToString());
- }
- throw new COMException(Ошибка);
- }
- // Так как параметры могут изменяться (OUT) и передаются по ссылке
- // нужно обратно обернуть параметры
- УстановитьИзмененияВМассиве(argsOrig, args);
- return ОбернутьОбъект(obj);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement