From 2165632d1d4dcc1b40dd0a8f5ac5631f0b5d7157 Mon Sep 17 00:00:00 2001 From: dahall Date: Wed, 20 Jan 2021 16:53:12 -0700 Subject: [PATCH] Added InteropExtensions.SizeOf(object) method to calculate the size of an object in native memory. It will handle blittalbe structures, primitives, strings and arrays or enumerable lists of those items. --- Core/Extensions/InteropExtensions.cs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Core/Extensions/InteropExtensions.cs b/Core/Extensions/InteropExtensions.cs index 2c8c8938..aa5be9a4 100644 --- a/Core/Extensions/InteropExtensions.cs +++ b/Core/Extensions/InteropExtensions.cs @@ -505,6 +505,31 @@ namespace Vanara.Extensions return type.IsEnum ? Marshal.SizeOf(Enum.GetUnderlyingType(type)) : Marshal.SizeOf(type); } + /// Returns the native memory size of a value, if possible. + /// The value whose native size is to be returned. + /// The character set to use for the strings. + /// The size, in bytes, of the value that is specified by the parameter. + /// Unable to get the size of the value. + public static SizeT SizeOf(object value, CharSet charSet = CharSet.Auto) + { + if (value is null) return 0; + if (value is string s) return StringHelper.GetByteCount(s, true, charSet); + var valType = value.GetType(); + var elemType = valType.FindElementType(); + if (elemType is null) + return SizeOf(valType); + if (elemType == typeof(string)) + return ((System.Collections.IEnumerable)value).Cast().Sum(s => StringHelper.GetByteCount(s, true, charSet)) + StringHelper.GetCharSize(); + if (valType.IsArray) + return ((Array)value).Length * SizeOf(elemType); + if (value is System.Collections.ICollection ic) + return ic.Count * SizeOf(elemType); + if (value is System.Collections.IEnumerable ie) + return ie.Cast().Count() * SizeOf(elemType); + + throw new ArgumentException("Unable to get the size of the value."); + } + /// Marshals data from a managed object to an unmanaged block of memory that is allocated using . /// The type of the managed object. ///