From e34e562d892cfebc67407f7d3a0f9a725e1cd67a Mon Sep 17 00:00:00 2001 From: Oskar Dudycz Date: Sat, 8 Oct 2022 10:23:06 +0200 Subject: [PATCH] Updated ObjectFactory implementation to use Expression with memoization to create new object instead of Activator. --- src/Ogooreck/Factories/ObjectFactory.cs | 55 +++++++++++-------------- src/Ogooreck/Ogooreck.csproj | 2 +- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/Ogooreck/Factories/ObjectFactory.cs b/src/Ogooreck/Factories/ObjectFactory.cs index 5344fce..d15e2bf 100644 --- a/src/Ogooreck/Factories/ObjectFactory.cs +++ b/src/Ogooreck/Factories/ObjectFactory.cs @@ -1,40 +1,33 @@ -using System.Runtime.CompilerServices; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.Serialization; + +#pragma warning disable CS1591 + namespace Ogooreck.Factories; -/// -/// Wraps objects creation -/// -/// public static class ObjectFactory { - /// - /// Creates empty unitialised instance of object T - /// - /// - public static T GetUnitialized() => - (T)RuntimeHelpers.GetUninitializedObject(typeof(T)); + public static readonly Func GetDefaultOrUninitialized = Creator(); - /// - /// Creates empty unitialised instance of object T - /// - /// - public static T? GetDefault() + private static Func Creator() { - try - { - return (T?)Activator.CreateInstance(typeof(T), true); - } - catch (MissingMethodException? e) - { - Console.WriteLine(e); - return default; - } + var t = typeof(T); + if (t == typeof(string)) + return Expression.Lambda>(Expression.Constant(string.Empty)).Compile(); + + if (t.HasDefaultConstructor()) + return Expression.Lambda>(Expression.New(t)).Compile(); + + return () => (T)FormatterServices.GetUninitializedObject(t); } +} - /// - /// Creates empty unitialised instance of object T - /// - /// - public static T GetDefaultOrUninitialized() - => GetDefault() ?? GetUnitialized(); +public static class ObjectFactory +{ + public static bool HasDefaultConstructor(this Type t) + { + return t.IsValueType || t.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + null, Type.EmptyTypes, null) != null; + } } diff --git a/src/Ogooreck/Ogooreck.csproj b/src/Ogooreck/Ogooreck.csproj index aaba347..c884ce8 100644 --- a/src/Ogooreck/Ogooreck.csproj +++ b/src/Ogooreck/Ogooreck.csproj @@ -1,7 +1,7 @@ - 0.5.0 + 0.5.1 net6.0 true true