예제 #1
0
            internal void AddInterfaceImpl([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type iface)
            {
                // If necessary, generate an attribute to permit visibility
                // to internal types.
                _assembly.EnsureTypeIsVisible(iface);

                _tb.AddInterfaceImplementation(iface);

                // AccessorMethods -> Metadata mappings.
                var propertyMap = new Dictionary <MethodInfo, PropertyAccessorInfo>();

                foreach (PropertyInfo pi in iface.GetRuntimeProperties())
                {
                    var ai = new PropertyAccessorInfo(pi.GetMethod, pi.SetMethod);
                    if (pi.GetMethod != null)
                    {
                        propertyMap[pi.GetMethod] = ai;
                    }
                    if (pi.SetMethod != null)
                    {
                        propertyMap[pi.SetMethod] = ai;
                    }
                }

                var eventMap = new Dictionary <MethodInfo, EventAccessorInfo>();

                foreach (EventInfo ei in iface.GetRuntimeEvents())
                {
                    var ai = new EventAccessorInfo(ei.AddMethod, ei.RemoveMethod, ei.RaiseMethod);
                    if (ei.AddMethod != null)
                    {
                        eventMap[ei.AddMethod] = ai;
                    }
                    if (ei.RemoveMethod != null)
                    {
                        eventMap[ei.RemoveMethod] = ai;
                    }
                    if (ei.RaiseMethod != null)
                    {
                        eventMap[ei.RaiseMethod] = ai;
                    }
                }

                foreach (MethodInfo mi in iface.GetRuntimeMethods())
                {
                    // Skip regular/non-virtual instance methods, static methods, and methods that cannot be overriden
                    // ("methods that cannot be overriden" includes default implementation of other interface methods).
                    if (!mi.IsVirtual || mi.IsFinal)
                    {
                        continue;
                    }

                    int methodInfoIndex = _methodInfos.Count;
                    _methodInfos.Add(mi);
                    MethodBuilder mdb = AddMethodImpl(mi, methodInfoIndex);
                    if (propertyMap.TryGetValue(mi, out PropertyAccessorInfo? associatedProperty))
                    {
                        if (mi.Equals(associatedProperty.InterfaceGetMethod))
                        {
                            associatedProperty.GetMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedProperty.SetMethodBuilder = mdb;
                        }
                    }

                    if (eventMap.TryGetValue(mi, out EventAccessorInfo? associatedEvent))
                    {
                        if (mi.Equals(associatedEvent.InterfaceAddMethod))
                        {
                            associatedEvent.AddMethodBuilder = mdb;
                        }
                        else if (mi.Equals(associatedEvent.InterfaceRemoveMethod))
                        {
                            associatedEvent.RemoveMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedEvent.RaiseMethodBuilder = mdb;
                        }
                    }
                }

                foreach (PropertyInfo pi in iface.GetRuntimeProperties())
                {
                    PropertyAccessorInfo ai = propertyMap[pi.GetMethod ?? pi.SetMethod !];
            internal void AddInterfaceImpl(Type iface)
            {
                // If necessary, generate an attribute to permit visibility
                // to internal types.
                _assembly.EnsureTypeIsVisible(iface);

                _tb.AddInterfaceImplementation(iface);

                // AccessorMethods -> Metadata mappings.
                var propertyMap = new Dictionary <MethodInfo, PropertyAccessorInfo>(MethodInfoEqualityComparer.Instance);

                foreach (var pi in iface.GetRuntimeProperties())
                {
                    var ai = new PropertyAccessorInfo(pi.GetMethod, pi.SetMethod);
                    if (pi.GetMethod != null)
                    {
                        propertyMap[pi.GetMethod] = ai;
                    }
                    if (pi.SetMethod != null)
                    {
                        propertyMap[pi.SetMethod] = ai;
                    }
                }

                var eventMap = new Dictionary <MethodInfo, EventAccessorInfo>(MethodInfoEqualityComparer.Instance);

                foreach (var ei in iface.GetRuntimeEvents())
                {
                    var ai = new EventAccessorInfo(ei.AddMethod, ei.RemoveMethod, ei.RaiseMethod);
                    if (ei.AddMethod != null)
                    {
                        eventMap[ei.AddMethod] = ai;
                    }
                    if (ei.RemoveMethod != null)
                    {
                        eventMap[ei.RemoveMethod] = ai;
                    }
                    if (ei.RaiseMethod != null)
                    {
                        eventMap[ei.RaiseMethod] = ai;
                    }
                }

                foreach (var mi in iface.GetRuntimeMethods())
                {
                    // 排除静态方法
                    if (mi.IsStatic)
                    {
                        continue;
                    }

                    var mdb = AddMethodImpl(mi);
                    if (propertyMap.TryGetValue(mi, out var associatedProperty))
                    {
                        if (MethodInfoEqualityComparer.Instance.Equals(associatedProperty.InterfaceGetMethod, mi))
                        {
                            associatedProperty.GetMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedProperty.SetMethodBuilder = mdb;
                        }
                    }

                    if (eventMap.TryGetValue(mi, out var associatedEvent))
                    {
                        if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceAddMethod, mi))
                        {
                            associatedEvent.AddMethodBuilder = mdb;
                        }
                        else if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceRemoveMethod, mi))
                        {
                            associatedEvent.RemoveMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedEvent.RaiseMethodBuilder = mdb;
                        }
                    }
                }

                foreach (var pi in iface.GetRuntimeProperties())
                {
                    var ai = propertyMap[pi.GetMethod ?? pi.SetMethod];
                    var pb = _tb.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, pi.GetIndexParameters().Select(p => p.ParameterType).ToArray());
                    if (ai.GetMethodBuilder != null)
                    {
                        pb.SetGetMethod(ai.GetMethodBuilder);
                    }
                    if (ai.SetMethodBuilder != null)
                    {
                        pb.SetSetMethod(ai.SetMethodBuilder);
                    }
                }

                foreach (var ei in iface.GetRuntimeEvents())
                {
                    var ai = eventMap[ei.AddMethod ?? ei.RemoveMethod];
                    var eb = _tb.DefineEvent(ei.Name, ei.Attributes, ei.EventHandlerType);
                    if (ai.AddMethodBuilder != null)
                    {
                        eb.SetAddOnMethod(ai.AddMethodBuilder);
                    }
                    if (ai.RemoveMethodBuilder != null)
                    {
                        eb.SetRemoveOnMethod(ai.RemoveMethodBuilder);
                    }
                    if (ai.RaiseMethodBuilder != null)
                    {
                        eb.SetRaiseMethod(ai.RaiseMethodBuilder);
                    }
                }
            }
            internal void AddInterfaceImpl(Type iface)
            {
                // If necessary, generate an attribute to permit visibility
                // to internal types.
                _assembly.EnsureTypeIsVisible(iface);

                _tb.AddInterfaceImplementation(iface);

                // AccessorMethods -> Metadata mappings.
                var propertyMap = new Dictionary <MethodInfo, PropertyAccessorInfo>(MethodInfoEqualityComparer.Instance);

                foreach (PropertyInfo pi in iface.GetRuntimeProperties())
                {
                    var ai = new PropertyAccessorInfo(pi.GetMethod, pi.SetMethod);
                    if (pi.GetMethod != null)
                    {
                        propertyMap[pi.GetMethod] = ai;
                    }
                    if (pi.SetMethod != null)
                    {
                        propertyMap[pi.SetMethod] = ai;
                    }
                }

                var eventMap = new Dictionary <MethodInfo, EventAccessorInfo>(MethodInfoEqualityComparer.Instance);

                foreach (EventInfo ei in iface.GetRuntimeEvents())
                {
                    var ai = new EventAccessorInfo(ei.AddMethod, ei.RemoveMethod, ei.RaiseMethod);
                    if (ei.AddMethod != null)
                    {
                        eventMap[ei.AddMethod] = ai;
                    }
                    if (ei.RemoveMethod != null)
                    {
                        eventMap[ei.RemoveMethod] = ai;
                    }
                    if (ei.RaiseMethod != null)
                    {
                        eventMap[ei.RaiseMethod] = ai;
                    }
                }

                foreach (MethodInfo mi in iface.GetRuntimeMethods())
                {
                    // Skip regular/non-virtual instance methods, static methods, and methods that cannot be overriden
                    // ("methods that cannot be overriden" includes default implementation of other interface methods).
                    if (!mi.IsVirtual || mi.IsFinal)
                    {
                        continue;
                    }

                    MethodBuilder        mdb = AddMethodImpl(mi);
                    PropertyAccessorInfo associatedProperty;
                    if (propertyMap.TryGetValue(mi, out associatedProperty))
                    {
                        if (MethodInfoEqualityComparer.Instance.Equals(associatedProperty.InterfaceGetMethod, mi))
                        {
                            associatedProperty.GetMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedProperty.SetMethodBuilder = mdb;
                        }
                    }

                    EventAccessorInfo associatedEvent;
                    if (eventMap.TryGetValue(mi, out associatedEvent))
                    {
                        if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceAddMethod, mi))
                        {
                            associatedEvent.AddMethodBuilder = mdb;
                        }
                        else if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceRemoveMethod, mi))
                        {
                            associatedEvent.RemoveMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedEvent.RaiseMethodBuilder = mdb;
                        }
                    }
                }

                foreach (PropertyInfo pi in iface.GetRuntimeProperties())
                {
                    PropertyAccessorInfo ai = propertyMap[pi.GetMethod ?? pi.SetMethod];

                    // If we didn't make an overriden accessor above, this was a static property, non-virtual property,
                    // or a default implementation of a property of a different interface. In any case, we don't need
                    // to redeclare it.
                    if (ai.GetMethodBuilder == null && ai.SetMethodBuilder == null)
                    {
                        continue;
                    }

                    PropertyBuilder pb = _tb.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, pi.GetIndexParameters().Select(p => p.ParameterType).ToArray());
                    if (ai.GetMethodBuilder != null)
                    {
                        pb.SetGetMethod(ai.GetMethodBuilder);
                    }
                    if (ai.SetMethodBuilder != null)
                    {
                        pb.SetSetMethod(ai.SetMethodBuilder);
                    }
                }

                foreach (EventInfo ei in iface.GetRuntimeEvents())
                {
                    EventAccessorInfo ai = eventMap[ei.AddMethod ?? ei.RemoveMethod];

                    // If we didn't make an overriden accessor above, this was a static event, non-virtual event,
                    // or a default implementation of an event of a different interface. In any case, we don't
                    // need to redeclare it.
                    if (ai.AddMethodBuilder == null && ai.RemoveMethodBuilder == null && ai.RaiseMethodBuilder == null)
                    {
                        continue;
                    }

                    EventBuilder eb = _tb.DefineEvent(ei.Name, ei.Attributes, ei.EventHandlerType);
                    if (ai.AddMethodBuilder != null)
                    {
                        eb.SetAddOnMethod(ai.AddMethodBuilder);
                    }
                    if (ai.RemoveMethodBuilder != null)
                    {
                        eb.SetRemoveOnMethod(ai.RemoveMethodBuilder);
                    }
                    if (ai.RaiseMethodBuilder != null)
                    {
                        eb.SetRaiseMethod(ai.RaiseMethodBuilder);
                    }
                }
            }