The Labs \ Source Viewer \ SSCLI \ System \ OleAutBinder

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. // This class represents the Ole Automation binder.
  16. // #define DISPLAY_DEBUG_INFO
  17. namespace System
  18. {
  19.    
  20.     using System;
  21.     using System.Runtime.InteropServices;
  22.     using System.Reflection;
  23.     using Microsoft.Win32;
  24.     using CultureInfo = System.Globalization.CultureInfo;
  25.    
  26.     // Made serializable in anticipation of this class eventually having state.
  27.     [Serializable()]
  28.     internal class OleAutBinder : DefaultBinder
  29.     {
  30.         // ChangeType
  31.         // This binder uses OLEAUT to change the type of the variant.
  32.         public override object ChangeType(object value, Type type, CultureInfo cultureInfo)
  33.         {
  34.             Variant myValue = new Variant(value);
  35.             if (cultureInfo == null)
  36.                 cultureInfo = CultureInfo.CurrentCulture;
  37.            
  38.             #if DISPLAY_DEBUG_INFO
  39.             Console.Write("In OleAutBinder::ChangeType converting variant of type: ");
  40.             Console.Write(myValue.VariantType);
  41.             Console.Write(" to type: ");
  42.             Console.WriteLine(type.Name);
  43.             #endif
  44.            
  45.             if (type.IsByRef) {
  46.                 #if DISPLAY_DEBUG_INFO
  47.                 Console.WriteLine("Striping byref from the type to convert to.");
  48.                 #endif
  49.                 type = type.GetElementType();
  50.             }
  51.            
  52.             // If we are trying to convert from an object to another type then we don't
  53.             // need the OLEAUT change type, we can just use the normal COM+ mechanisms.
  54.             if (!type.IsPrimitive && type.IsInstanceOfType(value)) {
  55.                 #if DISPLAY_DEBUG_INFO
  56.                 Console.WriteLine("Source variant can be assigned to destination type");
  57.                 #endif
  58.                 return value;
  59.             }
  60.            
  61.             Type srcType = value.GetType();
  62.            
  63.             // Handle converting primitives to enums.
  64.             if (type.IsEnum && srcType.IsPrimitive) {
  65.                 #if DISPLAY_DEBUG_INFO
  66.                 Console.WriteLine("Converting primitive to enum");
  67.                 #endif
  68.                 return Enum.Parse(type, value.ToString());
  69.             }
  70.            
  71.             // Special case the convertion from DBNull.
  72.             if (srcType == typeof(DBNull)) {
  73.                 // The requested type is a DBNull so no convertion is required.
  74.                 if (type == typeof(DBNull))
  75.                     return value;
  76.                
  77.                 // Visual J++ supported converting from DBNull to null so customers
  78.                 // have requested (via a CDCR) that DBNull be convertible to null.
  79.                 // We don't however allow this when converting to a value class, since null
  80.                 // doesn't make sense for these, or to object since this would change existing
  81.                 // semantics.
  82.                 if ((type.IsClass && type != typeof(object)) || type.IsInterface)
  83.                     return null;
  84.             }
  85.            
  86.            
  87.             return base.ChangeType(value, type, cultureInfo);
  88.            
  89.         }
  90.        
  91.        
  92.         // CanChangeType
  93.         public override bool CanChangeType(object value, Type type, CultureInfo cultureInfo)
  94.         {
  95.             Variant myValue = new Variant(value);
  96.             if (cultureInfo == null)
  97.                 cultureInfo = CultureInfo.CurrentCulture;
  98.            
  99.             #if DISPLAY_DEBUG_INFO
  100.             Console.Write("In OleAutBinder::CanChangeType converting variant of type: ");
  101.             Console.Write(myValue.VariantType);
  102.             Console.Write(" to type: ");
  103.             Console.WriteLine(type.Name);
  104.             #endif
  105.            
  106.             // If we are trying to convert to variant then there is nothing to do.
  107.             if (type == typeof(Variant)) {
  108.                 #if DISPLAY_DEBUG_INFO
  109.                 Console.WriteLine("Variant being changed to type variant is always legal");
  110.                 #endif
  111.                 return true;
  112.             }
  113.            
  114.             if (type.IsByRef) {
  115.                 #if DISPLAY_DEBUG_INFO
  116.                 Console.WriteLine("Striping byref from the type to convert to.");
  117.                 #endif
  118.                 type = type.GetElementType();
  119.             }
  120.            
  121.             // If we are trying to convert from an object to another type then we don't
  122.             // need the OLEAUT change type, we can just use the normal COM+ mechanisms.
  123.             if (!type.IsPrimitive && type.IsInstanceOfType(value)) {
  124.                 #if DISPLAY_DEBUG_INFO
  125.                 Console.WriteLine("Source variant can be assigned to destination type");
  126.                 #endif
  127.                 return true;
  128.             }
  129.            
  130.             // Handle converting primitives to enums.
  131.             if (type.IsEnum && value.GetType().IsPrimitive) {
  132.                 #if DISPLAY_DEBUG_INFO
  133.                 Console.WriteLine("Converting primitive to enum");
  134.                 #endif
  135.                 return true;
  136.             }
  137.            
  138.             return base.CanChangeType(value, type, cultureInfo);
  139.         }
  140.     }
  141. }

Developer Fusion