I'd like to Reset
to there default values all of the members of my class instance CommunicationErrorsDetails
.
This class is part of a nested class MyNestedClassInstance
.
This is what I'd like to do :
MyNestedClassInstance.CommunicationErrorsDetails.Reset()
This a sample of my nested class MyNestedClass
which instance is MyNestedClassInstance
:
public class MyNestedClass : ICloneable
{
...
/// <summary>
/// Communication errors count
/// </summary>
public class CommunicationErrorsDetailsType : ICloneable
{
public int RetryCount;
public int CRCErrorCount;
public int DataBytesNotExpectedCount;
public int TooMuchDataReceivedCount;
public int ResponseDataAddressNotEqualCount;
public int BytesReceivedInCommunicationStateStartCount;
public int BytesReceivedInCommunicationStateSendFrameCount;
public int BytesReceivedInCommunicationStateDataResponseReceivedCount;
public int ExceptionCount;
public int NakcReceivedCount;
public int AckTimeoutCount;
public int DataTimeoutCount;
public double DataTimeoutRate;
public bool HasCommunicationErrors
{
get => RetryCount > 0
|| CRCErrorCount > 0
|| DataBytesNotExpectedCount > 0
|| TooMuchDataReceivedCount > 0
|| ResponseDataAddressNotEqualCount > 0
|| BytesReceivedInCommunicationStateStartCount > 0
|| BytesReceivedInCommunicationStateSendFrameCount > 0
|| BytesReceivedInCommunicationStateDataResponseReceivedCount > 0
|| ExceptionCount > 0
|| NakcReceivedCount > 0
|| AckTimeoutCount > 0
|| DataTimeoutCount > 0;
}
public object Clone()
{
return MemberwiseClone();
}
internal void Reset()
{
// ... ?
}
}
public CommunicationErrorsDetailsType CommunicationErrorsDetails = new CommunicationErrorsDetailsType();
...
// Other nested classes
...
}
How can I achieve Reset()
without having to recreate a new instance and without having to reset manually all members that can be of different types ?
All members are simple types (not classes).
Furthermore, I cannot change the structure of all classes of same type because we have several years of code structured like this.
Thank you for your help. Regards
Using Reflexion you can achieve what you want and with the help of DefaultExpression Class
internal void Reset()
{
// Retrieves only the fields of this Class
var bindingFlags = BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.Public;
List<FieldInfo> members = this.GetType()
.GetFields(bindingFlags)
.Where(f => f.MemberType == MemberTypes.Field)
.Where(value => value != null)
.ToList();
// Set all fields to its default type value
for (int i = 0; i < members.Count(); i++)
{
// This expression represents the default value of a type
// (0 for integer, null for a string, etc.)
Expression defaultExpr = Expression.Default(typeof(byte));
// The following statement first creates an expression tree,
// then compiles it, and then executes it.
var defaultValue = Expression.Lambda<Func<byte>>(defaultExpr).Compile()();
// Set the default value
members[i].SetValue(this, defaultValue);
}
}