From 6328efbc5b5d9a099c83e50ecc9c4add58bf464c Mon Sep 17 00:00:00 2001 From: Thomas Bargetz Date: Fri, 7 Jul 2017 10:57:12 +0200 Subject: [PATCH] Ignoring properties without a public setter or no setter at all --- .../Helpers/TestClassWithPrivateSetters.cs | 38 +++++++++++++++++++ S7.Net.UnitTest/S7.Net.UnitTest.csproj | 1 + S7.Net.UnitTest/S7NetTests.cs | 31 +++++++++++++++ S7.Net/Types/Class.cs | 31 ++++++++++----- 4 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 S7.Net.UnitTest/Helpers/TestClassWithPrivateSetters.cs diff --git a/S7.Net.UnitTest/Helpers/TestClassWithPrivateSetters.cs b/S7.Net.UnitTest/Helpers/TestClassWithPrivateSetters.cs new file mode 100644 index 0000000..0dd0522 --- /dev/null +++ b/S7.Net.UnitTest/Helpers/TestClassWithPrivateSetters.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace S7.Net.UnitTest.Helpers +{ + class TestClassWithPrivateSetters : TestClass + { + public const int PRIVATE_SETTER_VALUE = 42; + public const int PROTECTED_SETTER_VALUE = 1337; + public const int INTERNAL_SETTER_VALUE = 31137; + public const int JUST_A_GETTER_VALUE = 4711; + + public int PrivateSetterProperty + { + get { return PRIVATE_SETTER_VALUE; } + private set { throw new NotSupportedException("Shouldn't access private setter"); } + } + + public int ProtectedSetterProperty + { + get { return PROTECTED_SETTER_VALUE; } + private set { throw new NotSupportedException("Shouldn't access protected setter"); } + } + + public int InternalSetterProperty + { + get { return INTERNAL_SETTER_VALUE; } + private set { throw new NotSupportedException("Shouldn't access internal setter"); } + } + + public int JustAGetterProperty + { + get { return JUST_A_GETTER_VALUE; } + } + } +} diff --git a/S7.Net.UnitTest/S7.Net.UnitTest.csproj b/S7.Net.UnitTest/S7.Net.UnitTest.csproj index 025cc39..cc2f72c 100644 --- a/S7.Net.UnitTest/S7.Net.UnitTest.csproj +++ b/S7.Net.UnitTest/S7.Net.UnitTest.csproj @@ -56,6 +56,7 @@ + diff --git a/S7.Net.UnitTest/S7NetTests.cs b/S7.Net.UnitTest/S7NetTests.cs index f6e9b4c..096f6f6 100644 --- a/S7.Net.UnitTest/S7NetTests.cs +++ b/S7.Net.UnitTest/S7NetTests.cs @@ -457,6 +457,37 @@ namespace S7.Net.UnitTest Assert.IsFalse(boolVariable); } + [TestMethod] + public void T12_ReadClassIgnoresNonPublicSetters() + { + Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor."); + + TestClassWithPrivateSetters tc = new TestClassWithPrivateSetters(); + tc.BitVariable00 = true; + tc.BitVariable10 = true; + tc.DIntVariable = -100000; + tc.IntVariable = -15000; + tc.RealVariable = -154.789; + tc.DWordVariable = 850; + + plc.WriteClass(tc, DB2); + + TestClassWithPrivateSetters tc2 = new TestClassWithPrivateSetters(); + // Values that are read from a class are stored inside the class itself, that is passed by reference + plc.ReadClass(tc2, DB2); + Assert.AreEqual(tc.BitVariable00, tc2.BitVariable00); + Assert.AreEqual(tc.BitVariable10, tc2.BitVariable10); + Assert.AreEqual(tc.DIntVariable, tc2.DIntVariable); + Assert.AreEqual(tc.IntVariable, tc2.IntVariable); + Assert.AreEqual(tc.RealVariable, Math.Round(tc2.RealVariable, 3)); + Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable); + + Assert.AreEqual(TestClassWithPrivateSetters.PRIVATE_SETTER_VALUE, tc2.PrivateSetterProperty); + Assert.AreEqual(TestClassWithPrivateSetters.PROTECTED_SETTER_VALUE, tc2.ProtectedSetterProperty); + Assert.AreEqual(TestClassWithPrivateSetters.INTERNAL_SETTER_VALUE, tc2.InternalSetterProperty); + Assert.AreEqual(TestClassWithPrivateSetters.JUST_A_GETTER_VALUE, tc2.JustAGetterProperty); + } + #endregion #region Private methods diff --git a/S7.Net/Types/Class.cs b/S7.Net/Types/Class.cs index 477ee7c..3afbbe8 100644 --- a/S7.Net/Types/Class.cs +++ b/S7.Net/Types/Class.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; namespace S7.Net.Types @@ -8,16 +10,26 @@ namespace S7.Net.Types /// public static class Class { + private static IEnumerable GetAccessableProperties(Type classType) + { + return classType + .GetProperties( + BindingFlags.SetProperty | + BindingFlags.Public | + BindingFlags.Instance) + .Where(p => p.GetSetMethod() != null); + } + /// - /// Gets the size of the struct in bytes. + /// Gets the size of the class in bytes. /// /// the type of the class /// the number of bytes public static int GetClassSize(Type classType) { - double numBytes = 0.0; - - var properties = classType.GetProperties(); + double numBytes = 0.0; + + var properties = GetAccessableProperties(classType); foreach (var property in properties) { switch (property.PropertyType.Name) @@ -59,12 +71,11 @@ namespace S7.Net.Types } /// - /// Creates a struct of a specified type by an array of bytes. + /// Sets the object's values with the given array of bytes /// - /// - /// The struct type + /// The object to fill in the given array of bytes + /// The class type /// The array of bytes - /// The object depending on the struct type or null if fails(array-length != struct-length public static void FromBytes(object sourceClass, Type classType, byte[] bytes) { if (bytes == null) @@ -79,7 +90,7 @@ namespace S7.Net.Types double numBytes = 0.0; - var properties = sourceClass.GetType().GetProperties(); + var properties = GetAccessableProperties(classType); foreach (var property in properties) { switch (property.PropertyType.Name) @@ -181,7 +192,7 @@ namespace S7.Net.Types int bitPos = 0; double numBytes = 0.0; - var properties = sourceClass.GetType().GetProperties(); + var properties = GetAccessableProperties(sourceClass.GetType()); foreach (var property in properties) { bytes2 = null;