I have a data structure that I am trying to represent by means of some classes (windows forms), but I am concerned about whether I can restrict the length of the strings that are going to be entered.
Now, an example class as I am representing it would be the following:
public class RipsAF
{
public string CodigoPrestador { get; set; }
public string NombreProveedor { get; set; }
public string TipoIdentificacion { get; set; }
public string NumeIdentificacion { get; set; }
public string NumFactura { get; set; }
}
But, for example, I want to restrict the property CodigoPrestador
where it doesn't support strings longer than 10 characters.
If you want to implement some logic in the properties of your class, you should NOT use Auto-Implemented Properties. You must define a field (field) and then write your property. After that in the setter set the logic you require (in your case validate the size) and throw an exception or discard the invalid value. I only put the example in the property
CodigoPrestador
You can limit the length of your object's property by
Substring()
defining the maximum length , here's an example:An example suitable to your code, for example if you define limit the property
NumFactura
to 10 characters in eitherget
:or in
set
:To check instances of the class, you store the value and then get it limited to 10 characters:
You will have an output value:
Although validation can be done in the way proposed in the other answers, if you have multiple classes and multiple properties on each class, a lot of repeated code is required to check the length of each string. And that quickly becomes very tedious.
For example, if we take the class
RipsAF
in your question:...and decide to apply length constraints to each string, the code results in something much more verbose (based on @Sergio Parra's answer, but applying validation to each property and adjusted so that it doesn't fail when the value is
null
):Maybe it's just my opinion, but I don't really like the result.
Workaround: Using a dynamic proxy
What if we could extract the logic that checks the length of the strings and centralize it to prevent the class from being polluted by repetitive code? Well this can be achieved using attributes and dynamic proxies .
The basic idea is the following:
Several popular frameworks use this technique, often without us realizing how they do it (example: Entity Framework).
Using this technique, we can express the class
RipsAF
in this much simpler and clearer way:As you can see, it's just a matter of adding the attribute
MaxLength
to the properties that need the maximum length to be validated.The other detail is that you have to mark the properties with the keyword
virtual
. The reason is that, in order to validate the strings, the proxy needs to intercept the property calls. And the way this interception is achieved is by inheriting from the class in question and modifying the implementation of the properties automatically. But this can only be achieved with checked propertiesvirtual
.Now, that's the easy part. The trickiest part is writing the code that creates the dynamic proxy and intercepts the property calls.
But as a gift, I leave here the code that handles that part and that can create the proxy for any class. (I can't explain every detail of this code, because my answer is already getting too long. But for those of you who are interested, it's worth taking a closer look at the code.) For the code to work, you need to include the Castle library. Core in your project which can be found for free on NuGet :
Once you have this class
EntityBuilder<T>
included in your project, using it with the classRipsAF
, or any other class, is extremely easy:The second assignment to the property
CodigoPrestador
results in the following exception:final notes
Recognize the complexity of writing the code that creates the dynamic proxy that automatically intercepts properties. The implementation of the class
EntityBuilder<T>
is proof of that.But using this technique has interesting advantages: