Syntactic versus Semantic Conversion
At first blush, it may seem very straightforward to convert attribute values into the types we want. We can either check the type information at runtime using the .NET Framework's language support, or look up schema information (either programmatically or by hand, referring to the reference material). Using this, we should be able to convert any data type into a meaningful representation.
Unfortunately, this is not always straightforward. While we can certainly determine syntax via type information, it is a much more difficult (and interesting) problem to determine semantics. For example, let's say we encounter an attribute that contains binary data. We can easily convert this into a byte array using the techniques we have presented here, but what does the binary data actually mean? It could represent a GUID (objectGUID), a security identifier or SID (objectSID), an X509 certificate (userCertificate), a JPEG file (jpegPhoto), or practically anything else. Another good example is a LargeInteger syntax value. Windows often uses these to represent dates in FILETIME format (pwdLastLet), but also uses them to represent time intervals (lockoutDuration) and sometimes just uses them to represent really big numbers (uSNChanged). So, how can we determine this information?
In the general case, we cannot. There is simply not enough information stored in the schema or available from the .NET type system at runtime to make these kinds of judgments. At some level, we have to "know" what the attribute data means so that we can interpret it in a more meaningful way.
At some point, we will find ourselves in a position where we must make semantic interpretations about LDAP data. Every interesting problem will involve this kind of work to some degree or another. The more general the problem we are trying to solve, the more difficult this exercise will become.