Skip to content

Commit

Permalink
Fixed a crash when reflecting on a write-only property.
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisdoomen committed Nov 23, 2024
1 parent b723530 commit d883c99
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
11 changes: 5 additions & 6 deletions src/Reflectify/Reflectify.cs
Original file line number Diff line number Diff line change
Expand Up @@ -647,9 +647,8 @@ private void AddNormalProperties(MemberKind kind, PropertyInfo[] allProperties)

private static bool HasVisibility(MemberKind kind, PropertyInfo prop)
{
return (kind.HasFlag(MemberKind.Public) && prop.GetMethod?.IsPublic is true) ||
(kind.HasFlag(MemberKind.Internal) &&
(prop.GetMethod?.IsAssembly is true || prop.GetMethod?.IsFamilyOrAssembly is true));
return (kind.HasFlag(MemberKind.Public) && prop.IsPublic()) ||
(kind.HasFlag(MemberKind.Internal) && prop.IsInternal());
}

private void AddExplicitlyImplementedProperties(MemberKind kind, PropertyInfo[] allProperties)
Expand Down Expand Up @@ -678,12 +677,12 @@ private void AddInterfaceProperties(Type typeToReflect, MemberKind kind, Binding
{
var interfaces = typeToReflect.GetInterfaces();

foreach (var iface in interfaces)
foreach (var interfaceType in interfaces)
{
foreach (var prop in iface.GetProperties(flags))
foreach (var prop in interfaceType.GetProperties(flags))
{
if (!collectedPropertyNames.Contains(prop.Name) &&
(!prop.GetMethod.IsAbstract || typeToReflect.IsInterface))
(!prop.IsAbstract() || typeToReflect.IsInterface))
{
selectedProperties.Add(prop);
collectedPropertyNames.Add(prop.Name);
Expand Down
25 changes: 23 additions & 2 deletions tests/Reflectify.Specs/TypeMemberExtensionsSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,19 @@ public void Can_get_internal_properties()
});
}

[Fact]
public void Can_get_write_only_properties()
{
// Act
var properties = typeof(ClassImplementingSetterOnlyInterface)
.GetProperties(MemberKind.Public | MemberKind.DefaultInterfaceProperties | MemberKind.ExplicitlyImplemented);

// Assert
properties.Should().BeEquivalentTo([
new { Name = "WriteOnlyProperty", PropertyType = typeof(string) }
]);
}

[Fact]
public void Will_ignore_indexers()
{
Expand Down Expand Up @@ -702,7 +715,6 @@ public void Can_find_the_explicit_convertor_for_a_specific_source_and_target_typ
var convertor = typeof(ClassWithConversionOperators)
.FindExplicitConversionOperator(typeof(ClassWithConversionOperators), typeof(int));


// Assert
convertor.Should().NotBeNull();
convertor.ReturnType.Should().Be<int>();
Expand All @@ -726,7 +738,6 @@ public void Can_find_the_implicit_convertor_for_a_specific_source_and_target_typ
var convertor = typeof(ClassWithConversionOperators)
.FindImplicitConversionOperator(typeof(ClassWithConversionOperators), typeof(string));


// Assert
convertor.Should().NotBeNull();
convertor.ReturnType.Should().Be<string>();
Expand Down Expand Up @@ -811,6 +822,16 @@ private interface IInterfaceWithSingleProperty
string ExplicitlyImplementedProperty { get; set; }
}

private class ClassImplementingSetterOnlyInterface : IWithSetterOnlyProperty
{
public string WriteOnlyProperty { private get; set; }
}

private interface IWithSetterOnlyProperty
{
string WriteOnlyProperty { set; }
}

private sealed class ClassWithIndexer
{
[UsedImplicitly]
Expand Down

0 comments on commit d883c99

Please sign in to comment.