diff --git a/src/Discord.Net/DynamicIL.cs b/src/Discord.Net/DynamicIL.cs index 07b2b2dbe..bce89424d 100644 --- a/src/Discord.Net/DynamicIL.cs +++ b/src/Discord.Net/DynamicIL.cs @@ -7,9 +7,9 @@ namespace Discord { internal static class DynamicIL { - public static Action CreateCloner() + public static Action CreateCopyMethod() { - var method = new DynamicMethod("CopyFields", null, new[] { typeof(T), typeof(T) }, typeof(T), true); + var method = new DynamicMethod("CopyTo", null, new[] { typeof(T), typeof(T) }, typeof(T), true); var generator = method.GetILGenerator(); var typeInfo = typeof(T).GetTypeInfo(); @@ -26,14 +26,24 @@ namespace Discord return method.CreateDelegate(typeof(Action)) as Action; } - public static void ForEachField(this TypeInfo typeInfo, Action fieldProcessor) + public static void ForEachField(this TypeInfo typeInfo, Action func) { var baseType = typeInfo.BaseType; if (baseType != null) - ForEachField(baseType.GetTypeInfo(), fieldProcessor); + baseType.GetTypeInfo().ForEachField(func); foreach (var field in typeInfo.DeclaredFields.Where(x => !x.IsStatic)) - fieldProcessor(field); + func(field); + } + public static void ForEachProperty(this TypeInfo typeInfo, Action func) + { + var baseType = typeInfo.BaseType; + if (baseType != null) + baseType.GetTypeInfo().ForEachProperty(func); + + foreach (var prop in typeInfo.DeclaredProperties.Where(x => + (!x.CanRead || !x.GetMethod.IsStatic) && (!x.CanWrite || !x.SetMethod.IsStatic))) + func(prop); } } } diff --git a/src/Discord.Net/Models/Channel.cs b/src/Discord.Net/Models/Channel.cs index 60b10e12f..505db8f25 100644 --- a/src/Discord.Net/Models/Channel.cs +++ b/src/Discord.Net/Models/Channel.cs @@ -14,7 +14,7 @@ namespace Discord { public class Channel : IMentionable { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); private struct Member { diff --git a/src/Discord.Net/Models/Color.cs b/src/Discord.Net/Models/Color.cs index c30f9737c..be8a14a18 100644 --- a/src/Discord.Net/Models/Color.cs +++ b/src/Discord.Net/Models/Color.cs @@ -4,7 +4,7 @@ namespace Discord { public class Color : IEquatable { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); public static readonly Color Default = PresetColor(0); diff --git a/src/Discord.Net/Models/Invite.cs b/src/Discord.Net/Models/Invite.cs index eac38bdfb..53ad22470 100644 --- a/src/Discord.Net/Models/Invite.cs +++ b/src/Discord.Net/Models/Invite.cs @@ -10,7 +10,7 @@ namespace Discord { public class Invite { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); public class ServerInfo { diff --git a/src/Discord.Net/Models/Message.cs b/src/Discord.Net/Models/Message.cs index 1f7733ed1..c1fd59bb8 100644 --- a/src/Discord.Net/Models/Message.cs +++ b/src/Discord.Net/Models/Message.cs @@ -24,7 +24,7 @@ namespace Discord public class Message { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); private static readonly Regex _userRegex = new Regex(@"<@[0-9]+>"); private static readonly Regex _channelRegex = new Regex(@"<#[0-9]+>"); diff --git a/src/Discord.Net/Models/Permissions.cs b/src/Discord.Net/Models/Permissions.cs index e992b748e..c842a8658 100644 --- a/src/Discord.Net/Models/Permissions.cs +++ b/src/Discord.Net/Models/Permissions.cs @@ -33,7 +33,7 @@ namespace Discord public class ServerPermissions : Permissions { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); public static ServerPermissions None { get; } = new ServerPermissions(); public static ServerPermissions All { get; } = new ServerPermissions(Convert.ToUInt32("00000011111100111111110000111111", 2)); @@ -62,7 +62,7 @@ namespace Discord public class ChannelPermissions : Permissions { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); public static ChannelPermissions None { get; } = new ChannelPermissions(); public static ChannelPermissions TextOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000000000000111111110000011001", 2)); @@ -169,7 +169,7 @@ namespace Discord public class DualChannelPermissions { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); public ChannelPermissions Allow { get; } public ChannelPermissions Deny { get; } diff --git a/src/Discord.Net/Models/Profile.cs b/src/Discord.Net/Models/Profile.cs index 077e0731c..859fe002d 100644 --- a/src/Discord.Net/Models/Profile.cs +++ b/src/Discord.Net/Models/Profile.cs @@ -8,7 +8,7 @@ namespace Discord { public class Profile { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); internal DiscordClient Client { get; } diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs index 8334baa63..5fb8d7102 100644 --- a/src/Discord.Net/Models/Role.cs +++ b/src/Discord.Net/Models/Role.cs @@ -11,7 +11,7 @@ namespace Discord { public class Role : IMentionable { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); internal DiscordClient Client => Server.Client; diff --git a/src/Discord.Net/Models/Server.cs b/src/Discord.Net/Models/Server.cs index 13f80572e..581e3b901 100644 --- a/src/Discord.Net/Models/Server.cs +++ b/src/Discord.Net/Models/Server.cs @@ -14,7 +14,7 @@ namespace Discord /// Represents a Discord server (also known as a guild). public class Server { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); internal static string GetIconUrl(ulong serverId, string iconId) => iconId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/${serverId}/icons/${iconId}.jpg" : null; diff --git a/src/Discord.Net/Models/User.cs b/src/Discord.Net/Models/User.cs index 2ae7223f5..7fff08f25 100644 --- a/src/Discord.Net/Models/User.cs +++ b/src/Discord.Net/Models/User.cs @@ -11,7 +11,7 @@ namespace Discord { public class User { - private readonly static Action _cloner = DynamicIL.CreateCloner(); + private readonly static Action _cloner = DynamicIL.CreateCopyMethod(); internal static string GetAvatarUrl(ulong userId, string avatarId) => avatarId != null ? $"{DiscordConfig.ClientAPIUrl}users/{userId}/avatars/{avatarId}.jpg" : null;