Skip to content

Release 0.2.0: array layout improvements, samples, version bump#50

Open
SergeyTeplyakov wants to merge 1 commit into
masterfrom
release/0.2.0
Open

Release 0.2.0: array layout improvements, samples, version bump#50
SergeyTeplyakov wants to merge 1 commit into
masterfrom
release/0.2.0

Conversation

@SergeyTeplyakov
Copy link
Copy Markdown
Owner

  • Expanded ArrayLayout with additional inspection support
  • Updates to FieldLayoutBase and ReflectionHelper
  • Added NullableTests coverage
  • Added samples/ folder with usage examples
  • Bump PackageVersion to 0.2.0.0 with updated release notes

- Expanded ArrayLayout with additional inspection support
- Updates to FieldLayoutBase and ReflectionHelper
- Added NullableTests coverage
- Added samples/ folder with usage examples
- Bump PackageVersion to 0.2.0.0 with updated release notes
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Release-focused update that expands ArrayLayout to support printing layouts for real array instances (including element values), improves reflection-based instantiation for nullable value types, adds regression coverage for nullable layouts, adds runnable sample scripts, and bumps the NuGet package version/release notes.

Changes:

  • Add array-instance inspection APIs (PrintLayout(Array|T[]), ToStringWithValues(Array)) and enhance array element rendering.
  • Improve nullable handling in ReflectionHelper.TryCreateInstanceSafe and clean compiler-generated field names in FieldLayout.
  • Add nullable regression tests and introduce samples/ usage examples; bump package version to 0.2.0.0.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/ObjectLayoutInspector/src/ObjectLayoutInspector/ObjectLayoutInspector.xml Updates generated XML docs for new ArrayLayout APIs.
src/ObjectLayoutInspector/ObjectLayoutInspector.csproj Bumps package version and updates release notes for 0.2.0.
src/ObjectLayoutInspector/Helpers/ReflectionHelper.cs Adjusts nullable value-type instantiation logic.
src/ObjectLayoutInspector/FieldLayoutBase.cs Cleans compiler-generated field names in layout output.
src/ObjectLayoutInspector/ArrayLayout.cs Adds array-instance “with values” rendering and nested struct formatting.
src/ObjectLayoutInspector.Tests/NullableTests.cs Adds regression + new coverage for nullable layouts and array value printing.
samples/StructLayout.cs Adds a file-based sample for struct layouts.
samples/NullableLayout.cs Adds a file-based sample for nullable layouts.
samples/CustomStruct.cs Adds a file-based sample for custom structs and array layout printing.
samples/ClassLayout.cs Adds a file-based sample for class layouts.
samples/ArrayLayout.cs Adds a file-based sample demonstrating array layout scenarios (primitive/struct/nullable/reference).

Comment on lines +62 to +64
return Nullable.GetUnderlyingType(t) != null
? Success(GetUninitializedObject(t))
: Success(Activator.CreateInstance(t));
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TryCreateInstanceSafe now uses GetUninitializedObject for Nullable<T>. GetUninitializedObject only catches TypeInitializationException, but FormatterServices.GetUninitializedObject can throw other exceptions (e.g., MemberAccessException/NotSupportedException). That means the "Try" method can throw for nullable value types, which breaks the method’s safe/try contract. Consider broadening the exception handling in GetUninitializedObject (or in this nullable branch) to return (null, false) instead of throwing.

Suggested change
return Nullable.GetUnderlyingType(t) != null
? Success(GetUninitializedObject(t))
: Success(Activator.CreateInstance(t));
if (Nullable.GetUnderlyingType(t) != null)
{
try
{
return Success(GetUninitializedObject(t));
}
catch (TypeInitializationException)
{
return (result: null, success: false);
}
catch (MemberAccessException)
{
return (result: null, success: false);
}
catch (NotSupportedException)
{
return (result: null, success: false);
}
}
return Success(Activator.CreateInstance(t));

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +86
if (name.Length > 2 && name[0] == '<')
{
int end = name.IndexOf('>');
if (end > 1)
return name.Substring(1, end - 1);
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CleanFieldName comment says it strips backing-field syntax (<PropertyName>k__BackingField), but the implementation strips any name starting with <...>, even if it’s not a backing field. Either tighten the logic to only strip known backing-field patterns (e.g., check for the k__BackingField suffix) or update the comment to match the broader behavior.

Suggested change
if (name.Length > 2 && name[0] == '<')
{
int end = name.IndexOf('>');
if (end > 1)
return name.Substring(1, end - 1);
}
const string backingFieldSuffix = "k__BackingField";
if (name.Length > backingFieldSuffix.Length + 2 && name[0] == '<')
{
int end = name.IndexOf('>');
if (end > 1
&& end + 1 + backingFieldSuffix.Length == name.Length
&& string.CompareOrdinal(name, end + 1, backingFieldSuffix, 0, backingFieldSuffix.Length) == 0)
{
return name.Substring(1, end - 1);
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +165 to +168
if (array.GetType().GetElementType() != ElementType)
throw new ArgumentException($"Array element type mismatch. Expected {ElementType.Name}.");
if (array.Length != Length)
throw new ArgumentException($"Array length mismatch. Expected {Length}, got {array.Length}.");
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ToStringWithValues throws ArgumentException for type/length mismatches but the messages omit the actual element type/length and don’t set the paramName. Including both expected/actual values and using nameof(array) would make failures easier to diagnose.

Suggested change
if (array.GetType().GetElementType() != ElementType)
throw new ArgumentException($"Array element type mismatch. Expected {ElementType.Name}.");
if (array.Length != Length)
throw new ArgumentException($"Array length mismatch. Expected {Length}, got {array.Length}.");
var actualElementType = array.GetType().GetElementType();
if (actualElementType != ElementType)
throw new ArgumentException(
$"Array element type mismatch. Expected {ElementType.Name}, got {actualElementType?.Name ?? "<null>"}.",
nameof(array));
if (array.Length != Length)
throw new ArgumentException(
$"Array length mismatch. Expected {Length}, got {array.Length}.",
nameof(array));

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants