From 48f9c6c7a91d9ac02b619a37125ddfbe15f5ca66 Mon Sep 17 00:00:00 2001 From: Michael Yarichuk Date: Sat, 17 Sep 2022 16:32:50 +0300 Subject: [PATCH] fix: ensure returning false when getter/setter is missing from property and trying to get/set value --- src/ObjectTreeWalker/ObjectAccessor.cs | 11 +++++- src/ObjectTreeWalker/ObjectIterator.cs | 23 ----------- src/ObjectTreeWalker/ObjectTreeWalker.cs | 3 ++ .../ObjectAccessorTests.cs | 38 +++++++++++++++++++ 4 files changed, 50 insertions(+), 25 deletions(-) delete mode 100644 src/ObjectTreeWalker/ObjectIterator.cs diff --git a/src/ObjectTreeWalker/ObjectAccessor.cs b/src/ObjectTreeWalker/ObjectAccessor.cs index 0942bca..1eed267 100644 --- a/src/ObjectTreeWalker/ObjectAccessor.cs +++ b/src/ObjectTreeWalker/ObjectAccessor.cs @@ -36,8 +36,15 @@ public ObjectAccessor(Type objectType) _objectType = objectType; foreach (var propertyInfo in objectType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)) { - _getPropertyMethods.Add(propertyInfo.Name, CreateGetPropertyFunc(propertyInfo)); - _setPropertyMethods.Add(propertyInfo.Name, CreateSetPropertyFunc(propertyInfo)); + if (propertyInfo.GetMethod != null) + { + _getPropertyMethods.Add(propertyInfo.Name, CreateGetPropertyFunc(propertyInfo)); + } + + if (propertyInfo.SetMethod != null) + { + _setPropertyMethods.Add(propertyInfo.Name, CreateSetPropertyFunc(propertyInfo)); + } } foreach (var fieldInfo in objectType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)) diff --git a/src/ObjectTreeWalker/ObjectIterator.cs b/src/ObjectTreeWalker/ObjectIterator.cs deleted file mode 100644 index 0ab4e44..0000000 --- a/src/ObjectTreeWalker/ObjectIterator.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Microsoft.Extensions.ObjectPool; - -namespace ObjectTreeWalker -{ - /// - /// A class that allows recursively iterating over object properties and fields - /// - public class ObjectIterator - { - private static readonly ObjectPool>> TraversalQueuePool = - new DefaultObjectPoolProvider().Create>>(); - - /* Unmerged change from project 'ObjectTreeWalker(net6.0)' - Before: - } - After: - } - */ - } -} diff --git a/src/ObjectTreeWalker/ObjectTreeWalker.cs b/src/ObjectTreeWalker/ObjectTreeWalker.cs index 3e59b25..9224e69 100644 --- a/src/ObjectTreeWalker/ObjectTreeWalker.cs +++ b/src/ObjectTreeWalker/ObjectTreeWalker.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using Microsoft.Extensions.ObjectPool; namespace ObjectTreeWalker { @@ -8,6 +9,8 @@ namespace ObjectTreeWalker public class ObjectMemberIterator { private static readonly ConcurrentDictionary ObjectAccessorCache = new(); + private static readonly ObjectPool>> TraversalQueuePool = + new DefaultObjectPoolProvider().Create>>(); /// /// Initializes a new instance of the class diff --git a/tests/ObjectTreeWalker.Tests/ObjectAccessorTests.cs b/tests/ObjectTreeWalker.Tests/ObjectAccessorTests.cs index ee96d0d..05e5987 100644 --- a/tests/ObjectTreeWalker.Tests/ObjectAccessorTests.cs +++ b/tests/ObjectTreeWalker.Tests/ObjectAccessorTests.cs @@ -13,6 +13,28 @@ internal class PublicFooBar public PrivateFooBar Bar { get; set; } = new(); } + internal class PublicFooBarNoSet + { + public int Foo { get; } = 123; + + public int Test123 = 555; + + public PrivateFooBar Bar { get; set; } = new(); + } + + internal class PublicFooBarNoGet + { + public int Foo + { + set => _foo = value; + } + + public int Test123 = 555; + private int _foo; + + public PrivateFooBar Bar { get; set; } = new(); + } + internal struct PublicFooBarStruct { public int Foo { get; set; } = 123; @@ -77,6 +99,13 @@ public void Can_get_public_value_type_property(Type type) Assert.Equal(123, value); } + [Fact] + public void Should_fail_get_public_value_no_get() + { + var accessor = new ObjectAccessor(typeof(PublicFooBarNoGet)); + Assert.False(accessor.TryGetValue(new PublicFooBarNoGet(), "Foo", out var value)); + } + [Theory] [InlineData(typeof(PublicFooBar))] [InlineData(typeof(PublicFooBarStruct))] @@ -137,6 +166,15 @@ public void Can_set_public_value_type_property(Type type) Assert.Equal(345, ((dynamic)obj).Foo); } + [Fact] + public void Should_fail_setting_property_without_set() + { + var accessor = new ObjectAccessor(typeof(PublicFooBarNoSet)); + var obj = new PublicFooBarNoSet(); + + Assert.False(accessor.TrySetValue(obj, "Foo", 345)); + } + [Theory] [InlineData(typeof(PublicFooBar))] [InlineData(typeof(PublicFooBarStruct))]