ARTICLE AD BOX
I want to restrict generic typeparams to a certain set of interfaces and their implementors and/or classes and their inherited child classes.
I my concrete case, I want that typeparams TIn and TRet for these methods
TRet EncrpytT<TRet, TIn>(TIn tinSource, ...) TRet DecrpytT<TRet, TIn>(TIn tinSource, ...)could only have the following types:
string, char[], byte[], IEnumerable<char>, IEnumerable<byte> // includes also List<byte> HashSet<byte>, ...Is this possible with where clause like
where TRet : { IEnumerable<byte>, String, byte[], char[], IEnumerable<char> }, TIn : { IEnumerable<byte>, String, byte[], char[], IEnumerable<char> }I only found that you can restrict types in where clause to one interface and all implementors or one class and all inherited classes, like
where TRet : IEnumerable<char>, TIn : IEnumerable<byte>Here is the concrete example, which I couldn't code nice enough:
/// <summary> /// DecrpytT generic decryption method /// </summary> /// <typeparam name="TRet">return type /// <see cref="T:string"/> /// <see cref="T:char[]"/> <see cref="T:IEnumerable{char}"/> /// <see cref="T:bytes[]"/> <see cref="T:IEnumerable{byte}"/> /// </typeparam> /// <typeparam name="TIn"></typeparam> /// <param name="tinSource">encrypted message</param> /// <param name="cryptKey">Unique deterministic user key to encrypt /// unique key for each symmetric cipher algorithm in each stage of pipe</param> /// <param name="decoding"><see cref="EncodingType"/> type for encoding encrypted bytes back in ascii-7 plain text></param> /// <param name="unzipAfter"><see cref="ZipType"/> and <see cref="ZipTypeExtensions.Unzip(ZipType, byte[])"/></param> /// <param name="keyHash"><see cref="KeyHash"/> key hashing algorithm</param> /// <param name="mode2"><see cref="Security.Cryptography.CipherMode"/></param> /// <returns>Decrypted generic TRet</returns> public static TRet DecrpytT<TRet, TIn>(TIn tinSource, string cryptKey, string hashIv, EncodingType decoding = EncodingType.Base64, ZipType unzipAfter = ZipType.None, KeyHash keyHash = KeyHash.Hex, CipherMode cmode = CipherMode.ECB) { hashIv = hashIv ?? keyHash.Hash(cryptKey); byte[] stringBytes = new List<byte>().ToArray(); // create symmetric cipher pipe for decryption with crypt key and pass pipeString as out param SymmCipherPipe symmPipe = new SymmCipherPipe(cryptKey, hashIv, decoding, unzipAfter, keyHash, cmode, true); string incomingEncoded = string.Empty; if (tinSource is string inString) incomingEncoded = inString; else if (tinSource is char[] chars) incomingEncoded = chars.ToString(); else if (tinSource is IEnumerable<char> charsIEnumerable) incomingEncoded = new string(charsIEnumerable.ToArray()); else if (tinSource is byte[] inBytes) incomingEncoded = System.Text.Encoding.UTF8.GetString(inBytes); else if (tinSource is IEnumerable<byte> bytesEnumerable) incomingEncoded = System.Text.Encoding.UTF8.GetString(bytesEnumerable.ToArray()); else throw new CException($"Unknown Type Exception, type {typeof(TIn)} is not supported."); // get bytes from encrypted encoded string dependent on the encoding type (uu, base64, base32,..) byte[] cipherBytes = decoding.GetEnCoder().Decode(incomingEncoded); // staged decryption of bytes byte[] intermediatBytes = symmPipe.DecrpytRoundGoMerry(cipherBytes, cryptKey, hashIv, cmode); // Unzip after if necessary byte[] decryptedBytes = (unzipAfter != ZipType.None) ? unzipAfter.Unzip(intermediatBytes) : intermediatBytes; TRet result = default(TRet); if (typeof(TRet) == typeof(string)) result = (TRet)(object)System.Text.Encoding.UTF8.GetString(decryptedBytes); else if (typeof(TRet) == typeof(char[])) result = (TRet)(object)System.Text.Encoding.UTF8.GetString(decryptedBytes).ToCharArray(); else if (typeof(TRet) == typeof(IEnumerable<char>)) result = (TRet)(object)System.Text.Encoding.UTF8.GetString(decryptedBytes).ToCharArray(); else if (typeof(TRet) == typeof(byte[])) result = (TRet)(object)decryptedBytes; else if (result is IEnumerable<byte> bytesIEnumerable) result = (TRet)(object)decryptedBytes; else throw new CException($"Unknown Type Exception, type {typeof(TRet)} is not supported."); return result; }