I need to enforce the members of a class derived from a base class to only have a certain type.
For example if I have a MustInherit Class Serializable
which has a method ToByteArray()
.
How can I restrict derived classes to only have fields which are specific types (for example restricted to having fields of type int, char or byte) so that I'm guaranteed to be able to serialize the class with the ToByteArray method which I have written.
The reason for this is because I want any derived classes to have a constant byte representation when it is serialized.
For example:
class Foo
Inherits Serializable
'Valid field as it is a char guaranteed to be two bytes
Public field1 As Char
'Valid field as it is a Int which is guaranteed to be two bytes
Public field2 As Integer
'**Invalid as a string can be a dynamic length which is not wanted in this context
Public field3 As String
End Class
Is this restriction possible in .net? vb.net in specific however I'm familiar with both and can convert between the two.
An idea I had was to throw a run-time error in the class Serializable
's constructor after looping through the fields using Reflection and comparing their types against a list of valid types. However this a is a weak solution as an invalid class would only be detected during run-time, rather than compile time.
Here is a SO question which tackles the same problem but is in C++ not C# (just for guidance as to the desired behavior if needed) How to enforce derived class members on derived classes
Update 9/2/2020 now that I've learned Unit Tests: Quite a simple solution is to use Reflection in a UnitTest
<TestMethod()>
Public Sub ShouldObeyTypeConstraintsTest()
Dim types As IEnumerable(Of Type) = From t In Assembly.GetAssembly(GetType(IRestricted)).GetTypes()
From i In t.GetInterfaces()
Where i.IsGenericType AndAlso (i.GetGenericTypeDefinition() Is GetType(IRestricted(Of )))
Select t
For Each type As Type In types
Dim info() As FieldInfo = serializable.GetFields()
For Each field In info
Dim fieldType As Type = field.FieldType()
If Not isValidType(fieldType) Then
Assert.Fail($"IRestricted type {serializable.FullName} has invalid field {fieldType.Name}")
End If
Next
Next
End Sub