Advertisement
Guest User

Untitled

a guest
May 14th, 2016
529
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.08 KB | None | 0 0
  1. [ClassInterface(ClassInterfaceType.AutoDispatch)]
  2.     [ComVisible(true)]
  3.     [Guid("1521B4B2-F38B-4CAD-BB45-3C6E1F00982F")]
  4.     public class AutoWrap : IReflect
  5.     {
  6.         protected internal object O = null;
  7.         protected internal Type T = null;
  8.  
  9.         FieldInfo[] Поля = null;
  10.         MemberInfo[] Мемберы = null;
  11.         internal MethodInfo[] Методы = null;
  12.         PropertyInfo[] Свойства = null;
  13.         //    Dictionary<string, FieldInfo> HashFieldInfo;
  14.  
  15.         BindingFlags staticBinding = BindingFlags.Public | BindingFlags.Static;
  16.  
  17.         internal bool ЭтоТип;
  18.         internal bool ЭтоExpandoObject;
  19.         public static bool ЭтоСемерка = false;
  20.         public static bool ВыводитьСообщениеОбОшибке = true;
  21.         public static Exception ПоследняяОшибка = null;
  22.         public static Dictionary<string, bool> МетодыObject;
  23.  
  24.         static AutoWrap()
  25.         {
  26.             МетодыObject = new Dictionary<string, bool>();
  27.             foreach (var метод in typeof(object).GetMethods(BindingFlags.Public | BindingFlags.Instance))
  28.                 МетодыObject[метод.Name] = true;
  29.  
  30.  
  31.         }
  32.         static Exception NotImplemented()
  33.         {
  34.             var method = new System.Diagnostics.StackTrace(true).GetFrame(1).GetMethod().Name;
  35.             System.Diagnostics.Debug.Assert(false, method);
  36.             return new NotImplementedException(method);
  37.         }
  38.  
  39.          void ДобавитьМетодыObject()
  40.         {
  41.  
  42.  
  43.         }
  44.         public static object ПолучитьРеальныйОбъект(object obj)
  45.         {
  46.  
  47.  
  48.             if (obj is AutoWrap)
  49.             {
  50.                 return ((AutoWrap)obj).O;
  51.             }
  52.  
  53.             return obj;
  54.         }
  55.  
  56.  
  57.  
  58.  
  59.         internal static object[] ПолучитьМассивРеальныхОбъектов(object[] args)
  60.         {
  61.             if (args.Length == 0)
  62.                 return args;
  63.  
  64.  
  65.             object[] res = new object[args.Length];
  66.  
  67.             for (int i = 0; i < args.Length; i++)
  68.             {
  69.                 res[i] = ПолучитьРеальныйОбъект(args[i]);
  70.             }
  71.  
  72.  
  73.  
  74.             return res;
  75.  
  76.  
  77.  
  78.         }
  79.  
  80.         internal static void УстановитьИзмененияВМассиве(object[] ОригинальныйМассив, object[] МассивРеальныхОбъектов)
  81.         {
  82.             if (ОригинальныйМассив == МассивРеальныхОбъектов)
  83.                 return;
  84.  
  85.             for (int i = 0; i < ОригинальныйМассив.Length; i++)
  86.             {
  87.  
  88.                 object obj = ОригинальныйМассив[i];
  89.                 if (obj is AutoWrap)
  90.                 {
  91.                     AutoWrap элемент = (AutoWrap)obj;
  92.                     if (!object.Equals(элемент.O, МассивРеальныхОбъектов[i]))
  93.                         ОригинальныйМассив[i] = ОбернутьОбъект(МассивРеальныхОбъектов[i]);
  94.  
  95.                 }
  96.                 else
  97.                 {
  98.                     if (!object.Equals(ОригинальныйМассив[i], МассивРеальныхОбъектов[i]))
  99.                         ОригинальныйМассив[i] = ОбернутьОбъект(МассивРеальныхОбъектов[i]);
  100.                 }
  101.             }
  102.  
  103.  
  104.         }
  105.  
  106.         public static object ОбернутьОбъект(object obj)
  107.         {
  108.             if (obj != null)
  109.             {
  110.                 //switch (obj.GetType().ToString())
  111.                 //{
  112.                 //    case "System.String":
  113.                 //    case "System.DateTime":
  114.                 //    case "System.Boolean":
  115.                 //    case "System.Byte":
  116.                 //    case "System.Char":
  117.                 //    case "System.Decimal":
  118.                 //    case "System.Double":
  119.                 //    case "System.Single": // Float                
  120.                 //    case "System.Int32":
  121.                 //    case "System.Int64": // Long
  122.                 //    case "System.SByte":
  123.                 //    case "System.Int16":// Short
  124.                 //    case "System.UInt32":
  125.                 //    case "System.UInt64":
  126.                 //    case "System.UInt16":
  127.                 //        break; // These Types do not get wrapped
  128.                 //    default:
  129.                 //        obj = new AutoWrap(obj); // Wrap Type
  130.                 //        break;
  131.                 //}
  132.                 // Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single.
  133.  
  134.  
  135.  
  136.                 Type Тип = obj.GetType();
  137.  
  138.                 if (Тип==typeof(System.IntPtr) || Тип==typeof(System.UIntPtr))
  139.                     return new AutoWrap(obj);
  140.  
  141.                 if (ЭтоСемерка)
  142.                 {
  143.                  
  144.                     if (Тип == typeof(System.Decimal)) return ((Decimal)obj).ToString(CultureInfo.InvariantCulture);
  145.                     if (Тип.IsPrimitive)
  146.                     {
  147.                         if ((Тип == typeof(System.Int64) || Тип == typeof(System.UInt32) || Тип == typeof(System.UInt64) || Тип == typeof(System.UInt16) || Тип == typeof(System.SByte)))
  148.                             obj = Convert.ChangeType(obj, typeof(string), CultureInfo.InvariantCulture);
  149.                     }
  150.                     else if (!(Тип == typeof(System.DateTime)
  151.                                || Тип == typeof(System.String)
  152.                                || Тип == typeof(System.Decimal)
  153.                                || Тип.IsCOMObject)
  154.                              )
  155.                         obj = new AutoWrap(obj);
  156.                 }
  157.                 else
  158.                 {
  159.                     if (Тип.IsArray)
  160.                     {
  161.                         Type ТипМассива = Тип.GetElementType();
  162.                         if (ТипМассива != null)
  163.                             Тип = ТипМассива;
  164.                     }
  165.  
  166.                     if (!(Тип.IsPrimitive
  167.                     || Тип == typeof(System.Decimal)
  168.                     || Тип == typeof(System.DateTime)
  169.                     || Тип == typeof(System.String)
  170.                     || Тип.IsCOMObject)
  171.                           )
  172.                         obj = new AutoWrap(obj);
  173.                 }
  174.             }
  175.             return obj;
  176.         }
  177.  
  178.  
  179.  
  180.         public AutoWrap(object obj)
  181.         {
  182.             O = obj;
  183.             if (O is Type)
  184.             {
  185.                 T = O as Type;
  186.                 ЭтоТип = true;
  187.             }
  188.             else
  189.             {
  190.                 T = O.GetType();
  191.                 ЭтоТип = false;
  192.                 ЭтоExpandoObject = O is System.Dynamic.ExpandoObject;
  193.             }
  194.  
  195.  
  196.  
  197.         }
  198.         public AutoWrap(object obj, Type type)
  199.         {
  200.             O = obj;
  201.             T = type;
  202.             ЭтоТип = false;
  203.          //   ЭтоExpandoObject = O is System.Dynamic.ExpandoObject;
  204.  
  205.         }
  206.  
  207.  
  208.         #region IReflect Members
  209.         public System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
  210.         {
  211.             if (ЭтоТип)
  212.                 return T.GetField(name, staticBinding);
  213.             else if (ЭтоExpandoObject)
  214.                 throw NotImplemented();
  215.             else
  216.                 return T.GetField(name, bindingAttr);
  217.         }    /* SNIP other IReflect methods */
  218.  
  219.  
  220.         public void ПроверитьНаДоступКПолям(ref System.Reflection.BindingFlags invokeAttr, int КоличествоПараметров)
  221.         {
  222.  
  223.             if ((
  224.                 (
  225.                 (invokeAttr & BindingFlags.PutDispProperty) == BindingFlags.PutDispProperty)
  226.                 || (invokeAttr.HasFlag(System.Reflection.BindingFlags.PutRefDispProperty))
  227.                 )
  228.                 && (КоличествоПараметров == 1))
  229.             {
  230.                 invokeAttr = invokeAttr | BindingFlags.SetField;
  231.  
  232.             }
  233.             else if (((invokeAttr & BindingFlags.GetProperty) == BindingFlags.GetProperty) && (КоличествоПараметров == 0))
  234.             {
  235.                 invokeAttr = invokeAttr | BindingFlags.GetField;
  236.  
  237.             }
  238.  
  239.         }
  240.  
  241.         public object InvokeMemberExpandoObject(string name, System.Reflection.BindingFlags invokeAttr, object[] args)
  242.         {
  243.  
  244.           if  (invokeAttr.HasFlag(BindingFlags.InvokeMethod))
  245.             {
  246.  
  247.                 return ((Delegate)((IDictionary<string, object>)((System.Dynamic.ExpandoObject)O))[name]).DynamicInvoke(args);
  248.             }
  249.  
  250.           if (invokeAttr.HasFlag(BindingFlags.GetField))
  251.             return ((IDictionary<string, object>)((System.Dynamic.ExpandoObject)O))[name];
  252.  
  253.             if (invokeAttr.HasFlag(BindingFlags.SetField))
  254.                 ((IDictionary<string, object>)((System.Dynamic.ExpandoObject)O))[name] = args[0];
  255.  
  256.             return null;
  257.     }
  258.         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)
  259.         {        // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)
  260.  
  261.             if (name == "[DISPID=-4]")
  262.             {
  263.                 IEnumVARIANT rez = new EnumVariantImpl(((System.Collections.IEnumerable)O).GetEnumerator());
  264.                   return rez;
  265.              
  266.             }
  267.  
  268.  
  269.             object[] args = ПолучитьМассивРеальныхОбъектов(argsOrig);
  270.  
  271.             culture = CultureInfo.InvariantCulture;
  272.  
  273.  
  274.  
  275.             // Invoke whatever needs be invoked!
  276.             object obj;
  277.  
  278.             try
  279.             {
  280.  
  281.                 if (T.IsEnum && !((invokeAttr & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod))
  282.                     return ОбернутьОбъект(Enum.Parse(T, name));
  283.  
  284.  
  285.                 //           if (ЭтоСемерка)
  286.                 ПроверитьНаДоступКПолям(ref invokeAttr, args.Length);
  287.  
  288.  
  289.                 if (ЭтоТип)
  290.                     obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
  291.                 else if (ЭтоExpandoObject)
  292.                 {
  293.                     if (invokeAttr.HasFlag(BindingFlags.InvokeMethod) && МетодыObject.ContainsKey(name))
  294.                         obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
  295.                     else
  296.                         obj = InvokeMemberExpandoObject(name, invokeAttr, args);
  297.                 }
  298.                 else
  299.                     obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
  300.  
  301.             }
  302.             catch (Exception e)
  303.             {
  304.                 ПоследняяОшибка = e;
  305.                 string Ошибка = "Ошибка в методе " + name + " " + e.Message + " " + e.Source;
  306.  
  307.                 if (e.InnerException != null)
  308.                     Ошибка = Ошибка + "\r\n" + e.InnerException.ToString();
  309.  
  310.                 if (ВыводитьСообщениеОбОшибке)
  311.                 {
  312.                 MessageBox.Show(Ошибка);
  313.                 MessageBox.Show(e.StackTrace);
  314.                 MessageBox.Show(invokeAttr.ToString());
  315.                 }
  316.                 throw new COMException(Ошибка);
  317.             }
  318.  
  319.             // Так как параметры могут изменяться (OUT) и передаются по ссылке
  320.             // нужно обратно обернуть параметры
  321.             УстановитьИзмененияВМассиве(argsOrig, args);
  322.  
  323.             return ОбернутьОбъект(obj);
  324.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement