static Type ResolveIReadOnlyCollection(Type declaredType, Type t) { #if WINRT if (CheckIsIReadOnlyCollectionExactly(declaredType.GetTypeInfo())) { return(declaredType); } foreach (Type intImplBasic in declaredType.GetTypeInfo().ImplementedInterfaces) { TypeInfo intImpl = intImplBasic.GetTypeInfo(); if (CheckIsIReadOnlyCollectionExactly(intImpl)) { return(intImplBasic); } } #else if (CheckIsIReadOnlyCollectionExactly(declaredType)) { return(declaredType); } foreach (Type intImpl in declaredType.GetInterfaces()) { if (CheckIsIReadOnlyCollectionExactly(intImpl)) { return(intImpl); } } #endif return(null); }
public static bool Implements(this Type self, string @namespace, string name) { if (self.Is("System", "Object")) { return(false); } if (self.Is(@namespace, name)) { return(true); } foreach (var intf in self.GetInterfaces()) { if (intf.Is(@namespace, name)) { return(true); } } var bt = self.BaseType; if (bt == null) { return(false); } return(bt.Implements(@namespace, name)); }
void GenerateProtocolProperties(Type type, HashSet <string> processed) { foreach (var i in type.GetInterfaces()) { if (!IsProtocolInterface(i, false, out var protocol)) { continue; } // the same protocol can be included more than once (interfaces) - but we must generate only once var pname = i.Name; if (processed.Contains(pname)) { continue; } processed.Add(pname); print(""); print($"// {pname} protocol members "); GenerateProperties(i); // also include base interfaces/protocols GenerateProtocolProperties(i, processed); } }
static Type [] TypeGetInterfaces(Type t, bool declonly) { if (t.IsGenericParameter) { return(new Type [0]); } Type [] ifaces = t.GetInterfaces(); if (!declonly) { return(ifaces); } // Handle Object. Also, optimize for no interfaces if (t.BaseType == null || ifaces.Length == 0) { return(ifaces); } ArrayList ar = new ArrayList(); foreach (Type i in ifaces) { if (!i.IsAssignableFrom(t.BaseType)) { ar.Add(i); } } return((Type [])ar.ToArray(typeof(Type))); }
static Type ResolveIReadOnlyCollection(Type declaredType, Type t) { #if WINRT foreach (Type intImplBasic in declaredType.GetTypeInfo().ImplementedInterfaces) { TypeInfo intImpl = intImplBasic.GetTypeInfo(); if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`")) { if(t != null) { Type[] typeArgs = intImpl.GenericTypeArguments; if (typeArgs.Length != 1 && typeArgs[0] != t) continue; } return intImplBasic; } } #else foreach (Type intImpl in declaredType.GetInterfaces()) { if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`")) { if(t != null) { Type[] typeArgs = intImpl.GetGenericArguments(); if (typeArgs.Length != 1 && typeArgs[0] != t) continue; } return intImpl; } } #endif return null; }
public IEnumerable <Type> SearchInterfaces(Type t) { yield return(t); foreach (Type @interface in t.GetInterfaces()) { foreach (Type baseInterface in SearchInterfaces(@interface)) { yield return(baseInterface); } } }
bool TryGetInterfaceMethod(Type type, string name, Type[] paramTypes, out MethodInfo result) { foreach (var i in type.GetInterfaces()) { result = i.GetMethod(name, _memberFlags, _binder, paramTypes, null); if (result != null || TryGetInterfaceMethod(i, name, paramTypes, out result)) return true; } result = null; return false; }
static Type ResolveIReadOnlyCollection(Type declaredType, Type t) { #if WINRT foreach (Type intImplBasic in declaredType.GetTypeInfo().ImplementedInterfaces) { TypeInfo intImpl = intImplBasic.GetTypeInfo(); if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`")) { if (t != null) { Type[] typeArgs = intImpl.GenericTypeArguments; if (typeArgs.Length != 1 && typeArgs[0] != t) { continue; } } return(intImplBasic); } } #else foreach (Type intImpl in declaredType.GetInterfaces()) { if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`")) { if (t != null) { Type[] typeArgs = intImpl.GetGenericArguments(); if (typeArgs.Length != 1 && typeArgs[0] != t) { continue; } } return(intImpl); } } #endif return(null); }
bool ImplementsInterface(Type a, Type b) { if (Compare(a, b)) { return(true); } foreach (var i in a.GetInterfaces()) { if (Compare(a, b) || ImplementsInterface(i, b)) { return(true); } } return(false); }
void FindInheritedInterfaceMethods(Type type, HashSet <string> masters, HashSet <MethodInfo> result) { if (!type.IsTypeBuilder()) { foreach (var i in type.GetInterfaces()) { FindInheritedInterfaceMethods(i, masters, result); } foreach (var mi in type.GetMethods()) { var master = mi.GetReflectedName(); if (mi.DeclaringType == type && !masters.Contains(master)) { result.Add(mi); masters.Add(master); } } } else if (type.IsGenericType) { var def = type.GetGenericTypeDefinition(); foreach (var i in def.GetInterfaces()) { FindInheritedInterfaceMethods(ParameterizeInterface(type, i), masters, result); } foreach (var mi in def.GetMethods()) { var master = mi.GetReflectedName(); if (mi.DeclaringType == def && !masters.Contains(master)) { result.Add(TypeBuilder.GetMethod(type, mi)); masters.Add(master); } } } }
public static bool IsAndroidSubclass(this IKVM.Reflection.Type type) { foreach (var @interface in type.GetInterfaces()) { if (@interface.Assembly.IsAndroidAssembly()) { return(true); } } do { if (type == null) { return(false); } if (type.Assembly.IsAndroidAssembly()) { return(true); } type = type.BaseType; } while (true); }
protected override void Generate(ProcessedType type) { Type t = type.Type; var aname = t.Assembly.GetName().Name.Sanitize(); var static_type = t.IsSealed && t.IsAbstract; var managed_name = NameGenerator.GetObjCName(t); List <string> conformed_protocols = new List <string> (); foreach (var i in t.GetInterfaces()) { if (protocols.Contains(i)) { conformed_protocols.Add(NameGenerator.GetObjCName(i)); } } var tbuilder = new ClassHelper(headers, implementation) { AssemblyQualifiedName = t.AssemblyQualifiedName, AssemblyName = aname, BaseTypeName = NameGenerator.GetTypeName(t.BaseType), Name = NameGenerator.GetTypeName(t), Namespace = t.Namespace, ManagedName = t.Name, Protocols = conformed_protocols, IsBaseTypeBound = types.Contains(t.BaseType), IsStatic = t.IsSealed && t.IsAbstract, MetadataToken = t.MetadataToken, }; tbuilder.BeginHeaders(); tbuilder.BeginImplementation(); var default_init = false; List <ProcessedConstructor> constructors; if (ctors.TryGetValue(t, out constructors)) { // First get the unavailable init ctor selectors in parent class var unavailableCtors = GetUnavailableParentCtors(t, constructors); if (unavailableCtors.Count() > 0) { // TODO: Print a #pragma mark once we have a well defined header structure http://nshipster.com/pragma/ foreach (var uctor in unavailableCtors) { var ctorparams = uctor.Constructor.GetParameters(); string name = "init"; string signature = ".ctor()"; if (ctorparams.Length > 0) { GetSignatures("initWith", uctor.Constructor.Name, uctor.Constructor, ctorparams, uctor.FallBackToTypeName, false, out name, out signature); } headers.WriteLine("/** This initializer is not available as it was not re-exposed from the base type"); headers.WriteLine(" * For more details consult https://github.com/mono/Embeddinator-4000/blob/master/docs/ObjC.md#constructors-vs-initializers"); headers.WriteLine(" */"); headers.WriteLine($"- (nullable instancetype){name} NS_UNAVAILABLE;"); headers.WriteLine(); } } foreach (var ctor in constructors) { var pcount = ctor.Constructor.ParameterCount; default_init |= pcount == 0; var parameters = ctor.Constructor.GetParameters(); string name = "init"; string signature = ".ctor()"; if (parameters.Length > 0) { GetSignatures("initWith", ctor.Constructor.Name, ctor.Constructor, parameters, ctor.FallBackToTypeName, false, out name, out signature); } var builder = new MethodHelper(headers, implementation) { AssemblySafeName = aname, ReturnType = "nullable instancetype", ManagedTypeName = t.FullName, MetadataToken = ctor.Constructor.MetadataToken, MonoSignature = signature, ObjCSignature = name, ObjCTypeName = managed_name, IsConstructor = true, IsValueType = t.IsValueType, IgnoreException = true, }; builder.WriteHeaders(); builder.BeginImplementation(); builder.WriteMethodLookup(); // TODO: this logic will need to be update for managed NSObject types (e.g. from XI / XM) not to call [super init] implementation.WriteLine("if (!_object) {"); implementation.Indent++; implementation.WriteLine($"MonoObject* __instance = mono_object_new (__mono_context.domain, {managed_name}_class);"); string postInvoke = String.Empty; var args = "nil"; if (pcount > 0) { Generate(parameters, false, out postInvoke); args = "__args"; } builder.WriteInvoke(args); implementation.Write(postInvoke); implementation.WriteLine("_object = mono_embeddinator_create_object (__instance);"); implementation.Indent--; implementation.WriteLine("}"); if (types.Contains(t.BaseType)) { implementation.WriteLine("return self = [super initForSuper];"); } else { implementation.WriteLine("return self = [super init];"); } builder.EndImplementation(); headers.WriteLine(); if (members_with_default_values.Contains(ctor.Constructor)) { default_init |= GenerateDefaultValuesWrappers(name, ctor.Constructor); } } } // generate an `init` for a value type (even if none was defined, the default one is usable) if (!default_init && t.IsValueType) { var builder = new MethodHelper(headers, implementation) { AssemblySafeName = aname, ReturnType = "nullable instancetype", ManagedTypeName = t.FullName, MonoSignature = ".ctor()", ObjCSignature = "init", ObjCTypeName = managed_name, IsConstructor = true, IsValueType = t.IsValueType, IgnoreException = true, }; builder.WriteHeaders(); builder.BeginImplementation(); // no call to `WriteMethodLookup` since there is not such method if we reached this case implementation.WriteLine("if (!_object) {"); implementation.Indent++; implementation.WriteLine($"MonoObject* __instance = mono_object_new (__mono_context.domain, {managed_name}_class);"); // no call to `WriteInvoke` since there is not such method if we reached this case implementation.WriteLine("_object = mono_embeddinator_create_object (__instance);"); implementation.Indent--; implementation.WriteLine("}"); if (types.Contains(t.BaseType)) { implementation.WriteLine("return self = [super initForSuper];"); } else { implementation.WriteLine("return self = [super init];"); } builder.EndImplementation(); headers.WriteLine(); default_init = true; } if (!default_init || static_type) { tbuilder.DefineNoDefaultInit(); } List <ProcessedProperty> props; if (properties.TryGetValue(t, out props)) { headers.WriteLine(); foreach (var pi in props) { Generate(pi); } } List <ProcessedFieldInfo> f; if (fields.TryGetValue(t, out f)) { headers.WriteLine(); foreach (var fi in f) { Generate(fi); } } List <ProcessedProperty> s; if (subscriptProperties.TryGetValue(t, out s)) { headers.WriteLine(); foreach (var si in s) { GenerateSubscript(si); } } List <ProcessedMethod> meths; if (methods.TryGetValue(t, out meths)) { headers.WriteLine(); foreach (var mi in meths) { Generate(mi); } } MethodInfo m; if (icomparable.TryGetValue(t, out m)) { var pt = m.GetParameters() [0].ParameterType; var builder = new ComparableHelper(headers, implementation) { ObjCSignature = $"compare:({managed_name} * _Nullable)other", AssemblySafeName = aname, MetadataToken = m.MetadataToken, ObjCTypeName = managed_name, ManagedTypeName = t.FullName, MonoSignature = $"CompareTo({NameGenerator.GetMonoName (pt)})", }; builder.WriteHeaders(); builder.WriteImplementation(); } if (equals.TryGetValue(t, out m)) { var builder = new EqualsHelper(headers, implementation) { AssemblySafeName = aname, MetadataToken = m.MetadataToken, ObjCTypeName = managed_name, ManagedTypeName = t.FullName, }; builder.WriteHeaders(); builder.WriteImplementation(); } if (hashes.TryGetValue(t, out m)) { var builder = new HashHelper(headers, implementation) { AssemblySafeName = aname, MetadataToken = m.MetadataToken, ObjCTypeName = managed_name, ManagedTypeName = t.FullName, }; builder.WriteHeaders(); builder.WriteImplementation(); } tbuilder.EndHeaders(); tbuilder.EndImplementation(); }
void ImportTypeBase (TypeSpec spec, MetaType type) { if (spec.Kind == MemberKind.Interface) spec.BaseType = TypeManager.object_type; else if (type.BaseType != null) { if (type.BaseType.IsGenericType) spec.BaseType = CreateType (type.BaseType, new DynamicTypeReader (type), true); else spec.BaseType = CreateType (type.BaseType); } var ifaces = type.GetInterfaces (); if (ifaces.Length > 0) { foreach (var iface in ifaces) { spec.AddInterface (CreateType (iface)); } } }
void ImportTypeBase (TypeSpec spec, MetaType type) { if (spec.Kind == MemberKind.Interface) spec.BaseType = module.Compiler.BuiltinTypes.Object; else if (type.BaseType != null) { TypeSpec base_type; if (!IsMissingType (type.BaseType) && type.BaseType.IsGenericType) base_type = CreateType (type.BaseType, new DynamicTypeReader (type), true); else base_type = CreateType (type.BaseType); spec.BaseType = base_type; } MetaType[] ifaces; #if STATIC ifaces = type.__GetDeclaredInterfaces (); if (ifaces.Length != 0) { foreach (var iface in ifaces) { var it = CreateType (iface); if (it == null) continue; spec.AddInterface (it); // Unfortunately not all languages expand inherited interfaces var bifaces = it.Interfaces; if (bifaces != null) { foreach (var biface in bifaces) { spec.AddInterface (biface); } } } } if (spec.BaseType != null) { var bifaces = spec.BaseType.Interfaces; if (bifaces != null) { // // Before adding base class interfaces close defined interfaces // on type parameter // var tp = spec as TypeParameterSpec; if (tp != null && tp.InterfacesDefined == null) { tp.InterfacesDefined = TypeSpec.EmptyTypes; } foreach (var iface in bifaces) spec.AddInterface (iface); } } #else ifaces = type.GetInterfaces (); if (ifaces.Length > 0) { foreach (var iface in ifaces) { spec.AddInterface (CreateType (iface)); } } #endif if (spec.MemberDefinition.TypeParametersCount > 0) { foreach (var tp in spec.MemberDefinition.TypeParameters) { ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ()); } } }
static Type [] TypeGetInterfaces (Type t, bool declonly) { if (t.IsGenericParameter) return new Type [0]; Type [] ifaces = t.GetInterfaces (); if (! declonly) return ifaces; // Handle Object. Also, optimize for no interfaces if (t.BaseType == null || ifaces.Length == 0) return ifaces; ArrayList ar = new ArrayList (); foreach (Type i in ifaces) if (! i.IsAssignableFrom (t.BaseType)) ar.Add (i); return (Type []) ar.ToArray (typeof (Type)); }
internal static MethodInfo ResolveListAdd(TypeModel model, Type listType, Type itemType, out bool isList) { #if WINRT TypeInfo listTypeInfo = listType.GetTypeInfo(); #else Type listTypeInfo = listType; #endif isList = model.MapType(ilist).IsAssignableFrom(listTypeInfo); Type[] types = { itemType }; MethodInfo add = Helpers.GetInstanceMethod(listTypeInfo, "Add", types); #if !NO_GENERICS if (add == null) { // fallback: look for ICollection<T>'s Add(typedObject) method bool forceList = listTypeInfo.IsInterface && model.MapType(typeof(System.Collections.Generic.IEnumerable <>)).MakeGenericType(types) #if WINRT .GetTypeInfo() #endif .IsAssignableFrom(listTypeInfo); #if WINRT TypeInfo constuctedListType = typeof(System.Collections.Generic.ICollection <>).MakeGenericType(types).GetTypeInfo(); #else Type constuctedListType = model.MapType(typeof(System.Collections.Generic.ICollection <>)).MakeGenericType(types); #endif if (forceList || constuctedListType.IsAssignableFrom(listTypeInfo)) { add = Helpers.GetInstanceMethod(constuctedListType, "Add", types); } } if (add == null) { #if WINRT foreach (Type tmpType in listTypeInfo.ImplementedInterfaces) #else foreach (Type interfaceType in listTypeInfo.GetInterfaces()) #endif { #if WINRT TypeInfo interfaceType = tmpType.GetTypeInfo(); #endif if (interfaceType.Name == "IProducerConsumerCollection`1" && interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition().FullName == "System.Collections.Concurrent.IProducerConsumerCollection`1") { add = Helpers.GetInstanceMethod(interfaceType, "TryAdd", types); if (add != null) { break; } } } } #endif if (add == null) { // fallback: look for a public list.Add(object) method types[0] = model.MapType(typeof(object)); add = Helpers.GetInstanceMethod(listTypeInfo, "Add", types); } if (add == null && isList) { // fallback: look for IList's Add(object) method add = Helpers.GetInstanceMethod(model.MapType(ilist), "Add", types); } return(add); }
public void GenerateFilter(Type type) { var is_abstract = AttributeManager.HasAttribute <AbstractAttribute> (type); var filter = AttributeManager.GetCustomAttribute <CoreImageFilterAttribute> (type); var base_type = AttributeManager.GetCustomAttribute <BaseTypeAttribute> (type); var type_name = type.Name; var native_name = base_type.Name ?? type_name; var base_name = base_type.BaseType.Name; // internal static CIFilter FromName (string filterName, IntPtr handle) filters.Add(type_name); // filters are now exposed as protocols so we need to conform to them var interfaces = String.Empty; foreach (var i in type.GetInterfaces()) { interfaces += $", I{i.Name}"; } // type declaration print("public{0} partial class {1} : {2}{3} {{", is_abstract ? " abstract" : String.Empty, type_name, base_name, interfaces); print(""); indent++; // default constructor - if type is not abstract string v; if (!is_abstract) { v = GetVisibility(filter.DefaultCtorVisibility); if (v.Length > 0) { print_generated_code(); print("{0}{1} () : base (\"{2}\")", v, type.Name, native_name); PrintEmptyBody(); } } // IntPtr constructor - always present var intptrctor_visibility = filter.IntPtrCtorVisibility; if (intptrctor_visibility == MethodAttributes.PrivateScope) { // since it was not generated code we never fixed the .ctor(IntPtr) visibility for unified if (XamcoreVersion >= 3) { intptrctor_visibility = MethodAttributes.FamORAssem; } else { intptrctor_visibility = MethodAttributes.Public; } } print_generated_code(); print("{0}{1} (IntPtr handle) : base (handle)", GetVisibility(intptrctor_visibility), type_name); PrintEmptyBody(); // NSObjectFlag constructor - always present (needed to implement NSCoder for subclasses) print_generated_code(); print("[EditorBrowsable (EditorBrowsableState.Advanced)]"); print("protected {0} (NSObjectFlag t) : base (t)", type_name); PrintEmptyBody(); // NSCoder constructor - all filters conforms to NSCoding print_generated_code(); print("[EditorBrowsable (EditorBrowsableState.Advanced)]"); print("[Export (\"initWithCoder:\")]"); print("public {0} (NSCoder coder) : base (NSObjectFlag.Empty)", type_name); print("{"); indent++; print("IntPtr h;"); print("if (IsDirectBinding) {"); indent++; print("h = global::{0}.Messaging.IntPtr_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle (\"initWithCoder:\"), coder.Handle);", ns.CoreObjCRuntime); indent--; print("} else {"); indent++; print("h = global::{0}.Messaging.IntPtr_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle (\"initWithCoder:\"), coder.Handle);", ns.CoreObjCRuntime); indent--; print("}"); print("InitializeHandle (h, \"initWithCoder:\");"); indent--; print("}"); print(""); // string constructor // default is protected (for abstract) but backward compatibility (XAMCORE_2_0) requires some hacks v = GetVisibility(filter.StringCtorVisibility); if (is_abstract && (v.Length == 0)) { v = "protected "; } if (v.Length > 0) { print_generated_code(); print("{0} {1} (string name) : base (CreateFilter (name))", v, type_name); PrintEmptyBody(); } // properties GenerateProperties(type); // protocols GenerateProtocolProperties(type, new HashSet <string> ()); indent--; print("}"); // namespace closing (it's optional to use namespaces even if it's a bad practice, ref #35283) if (indent > 0) { indent--; print("}"); } }
internal static Type GetListItemType(TypeModel model, Type listType) { Helpers.DebugAssert(listType != null); #if WINRT TypeInfo listTypeInfo = listType.GetTypeInfo(); if (listType == typeof(string) || listType.IsArray || !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(listTypeInfo)) { return(null); } #else if (listType == model.MapType(typeof(string)) || listType.IsArray || !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType)) { return(null); } #endif BasicList candidates = new BasicList(); #if WINRT foreach (MethodInfo method in listType.GetRuntimeMethods()) #else foreach (MethodInfo method in listType.GetMethods()) #endif { if (method.IsStatic || method.Name != "Add") { continue; } ParameterInfo[] parameters = method.GetParameters(); Type paramType; if (parameters.Length == 1 && !candidates.Contains(paramType = parameters[0].ParameterType)) { candidates.Add(paramType); } } string name = listType.Name; bool isQueueStack = name != null && (name.IndexOf("Queue", System.StringComparison.Ordinal) >= 0 || name.IndexOf("Stack", System.StringComparison.Ordinal) >= 0); #if !NO_GENERICS if (!isQueueStack) { TestEnumerableListPatterns(model, candidates, listType); #if WINRT foreach (Type iType in listTypeInfo.ImplementedInterfaces) { TestEnumerableListPatterns(model, candidates, iType); } #else foreach (Type iType in listType.GetInterfaces()) { TestEnumerableListPatterns(model, candidates, iType); } #endif } #endif #if WINRT // more convenient GetProperty overload not supported on all platforms foreach (PropertyInfo indexer in listType.GetRuntimeProperties()) { if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) { continue; } ParameterInfo[] args = indexer.GetIndexParameters(); if (args.Length != 1 || args[0].ParameterType != typeof(int)) { continue; } MethodInfo getter = indexer.GetMethod; if (getter == null || getter.IsStatic) { continue; } candidates.Add(indexer.PropertyType); } #else // more convenient GetProperty overload not supported on all platforms foreach (PropertyInfo indexer in listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) { continue; } ParameterInfo[] args = indexer.GetIndexParameters(); if (args.Length != 1 || args[0].ParameterType != model.MapType(typeof(int))) { continue; } candidates.Add(indexer.PropertyType); } #endif switch (candidates.Count) { case 0: return(null); case 1: return((Type)candidates[0]); case 2: if (CheckDictionaryAccessors(model, (Type)candidates[0], (Type)candidates[1])) { return((Type)candidates[0]); } if (CheckDictionaryAccessors(model, (Type)candidates[1], (Type)candidates[0])) { return((Type)candidates[1]); } break; } return(null); }
void ImportTypeBase(TypeSpec spec, MetaType type) { if (spec.Kind == MemberKind.Interface) spec.BaseType = TypeManager.object_type; else if (type.BaseType != null) { TypeSpec base_type; if (!IsMissingType (type.BaseType) && type.BaseType.IsGenericType) base_type = CreateType (type.BaseType, new DynamicTypeReader (type), true); else base_type = CreateType (type.BaseType); spec.BaseType = base_type; } MetaType[] ifaces; #if STATIC ifaces = type.__GetDeclaredInterfaces (); if (ifaces.Length != 0) { foreach (var iface in ifaces) spec.AddInterface (CreateType (iface)); } if (spec.BaseType != null) { var bifaces = spec.BaseType.Interfaces; if (bifaces != null) { foreach (var iface in bifaces) spec.AddInterface (iface); } } #else ifaces = type.GetInterfaces (); if (ifaces.Length > 0) { foreach (var iface in ifaces) { spec.AddInterface (CreateType (iface)); } } #endif }