Greg
Greg

Reputation: 11480

What in the interface is going on?

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

Answers (4)

Max
Max

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

goric
goric

Reputation: 11895

The only real differences here are:

  1. The methods take a different parameter type
  2. The methods return something (are not 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

Krumelur
Krumelur

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

Gabe Moothart
Gabe Moothart

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

Related Questions