public VariantPropertyDesc ResolveProperty( string propertyName, EventType[] variants) { // property numbers should start at zero since the serve as array index var propertyGetterCache = variantEventType.VariantPropertyGetterCache; propertyGetterCache.AddGetters(propertyName); EventPropertyGetterSPI getter = new VariantEventPropertyGetterAny(variantEventType, propertyName); return new VariantPropertyDesc(typeof(object), getter, true); }
public VariantPropertyDesc ResolveProperty( string propertyName, EventType[] variants) { var existsInAll = true; Type commonType = null; var mustCoerce = false; for (var i = 0; i < variants.Length; i++) { var type = variants[i].GetPropertyType(propertyName).GetBoxedType(); if (type == null) { existsInAll = false; continue; } if (commonType == null) { commonType = type; continue; } // compare types if (type == commonType) { continue; } // coercion if (type.IsNumeric()) { if (type.CanCoerce(commonType)) { mustCoerce = true; continue; } if (commonType.CanCoerce(type)) { mustCoerce = true; commonType = type; } } else if (commonType == typeof(object)) { continue; } else if (!type.IsBuiltinDataType()) { // common interface or base class ISet<Type> supersForType = new LinkedHashSet<Type>(); TypeHelper.GetBase(type, supersForType); supersForType.Remove(typeof(object)); if (supersForType.Contains(commonType)) { continue; // type implements or : common type } if (TypeHelper.IsSubclassOrImplementsInterface(commonType, type)) { commonType = type; // common type implements type continue; } // find common interface or type both implement ISet<Type> supersForCommonType = new LinkedHashSet<Type>(); TypeHelper.GetBase(commonType, supersForCommonType); supersForCommonType.Remove(typeof(object)); // Take common classes first, ignoring interfaces var found = false; foreach (var superClassType in supersForType) { if (!superClassType.IsInterface && supersForCommonType.Contains(superClassType)) { commonType = superClassType; found = true; break; } } if (found) { continue; } // Take common interfaces foreach (var superClassType in supersForType) { if (superClassType.IsInterface && supersForCommonType.Contains(superClassType)) { break; } } } commonType = typeof(object); } if (!existsInAll) { return null; } if (commonType == null) { return null; } // property numbers should start at zero since the serve as array index var propertyGetterCache = variantEventType.VariantPropertyGetterCache; propertyGetterCache.AddGetters(propertyName); EventPropertyGetterSPI getter; if (mustCoerce) { var caster = SimpleTypeCasterFactory.GetCaster(null, commonType); getter = new VariantEventPropertyGetterAnyWCast(variantEventType, propertyName, caster); } else { getter = new VariantEventPropertyGetterAny(variantEventType, propertyName); } return new VariantPropertyDesc(commonType, getter, true); }