Reputation: 11480
I'm currently trying to become a bit more familiar with interfaces and generics, so based on my goals and implementation I wrote:
public interface ICipher<T>
{
void EncryptData(T raw);
void DecryptData(T encrypted);
}
However a collegue said I shouldn't do it like that, he said I should do it like this:
public interface ICipher<TRaw, TEncrypt>
{
TEncrypt EncryptData(TRaw rawData);
TRaw DecryptData(TEncrypt encryptedData);
}
Shortly after he provided that, he had to go.
The problem though, why is that a better solution? What exactly is the differences? Aren't they both implementing Generics, the only thing I can think of is that TRaw
and TEncrypt
objects are to be returned.
Am I missing something here? What exactly is the difference here, can someone explain that?
Upvotes: 2
Views: 130
Reputation: 3593
It will allow you to use two different types for the decrypted and encrypted data. In your first implementation, the encrypted data type will always be the same as the decrypted data. That's fine if you're doing a string
hash that produces a string
but if you want to produce an integer
for instance, only the second implementation will work.
With the second implementation, nothing will force you to use two different types as well (i.e. you can still implement ICipher<string, string>
) : it is much more flexible than the first one.
In your first implementation, your methods won't return anything so I suppose you want to alter the parameter directly ; in this case I would expect a reference type, and that is something to clarify like this :
interface ICipher<T> where T : class
{
//...
}
The second implementation returns a value which is a better design ; if I were to implement the interface or use a class that implements it I would expect the methods to have a return value instead of altering the parameter sent.
Upvotes: 0
Reputation: 11895
The only real differences here are:
void
)Without knowing about your specific use case, it's hard to say which is better, but it seems that methods like Encrypt
and Decrypt
should return something...
Upvotes: 2
Reputation: 33058
There is no better or worse. It depends on the use case.
Just imagine how you would implement these interfaces.
class StringCipher : ICipher<string>
{
void EncryptData(string plaintextString);
void DecryptData(string ecnryptedString);
}
and
class StringCipher : ICipher<string, EncryptedContainerObject>
{
EncryptedContainerObject EncryptData(string plaintextString);
string DecryptData(EncryptedContainerObject encryptedObject);
}
The first version is meant to accept a string
, encrypt it and the result is expected to be a string
too.
The second version is more flexible: you put a string
in and get an object of your choice back (I made up the EncryptedContainerObject
, in reality it will often be of type byte[]
). Maybe you don't want your encrypted data to be a string
, but some entity that can directly be stored in a database?
Also: the first version lacks a return value or accessor for the encrypted data. How would you get it out of your implementation again?
Upvotes: 3
Reputation: 32112
If you try to implement the interface, I think the difference will be clear. The methods in your first interface are not actually returning any data - and presumably you want to return data from your methods.
The TRaw/TEncrypt difference is because usually after encryption you get back a different type - for instance, encrypting a string
and getting back a byte[]
.
However I don't really see the need for generics in this case. The output in particular will probably always be of the same type (byte[]
, or maybe string
if you want to base64-encode for convenience). Input could benefit from being generic, depending on how you are planning to implement the interface.
Upvotes: 0