Click here to Skip to main content
15,894,343 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello guys,

the thing i'm looking for is to use delegate for first time in whole my life, and the problem is i saw no tutorial or problem that the method have diffrent input signature in whole network, at last till now :|

my problem is that i wanna write a class, with 2 method, that these method use an other methods, with with differente input signature and same output...

like :

i have this method :

C#
myMethod(method)

{
   byte[] b=method;
}



and then users call these method with passing their wished method...

user 1:
C#
byte[] data;
string skey;

myMethod(AEncMethod(data,skey));



and user 2:

C#
string otherData;
string otherKey;
CipherMode cipherMode;

myMethod(BEncMethod(otherData,otherKey,cipherMode));


since it's first time i'm using delegate, if you also can explain it and use simple coding it will be best to help me understand and implement my own.

also i'm using .Net 2 since the result application gonna have all old and new user with diff os, i want use old framework so no Func or Action, though event didnt see one with Func :D

i'm wonder also if i should defain generics entity classes to pass my parameters also.
Posted

Not a specific answer to your question but you may want to research the Strategy Pattern[^]
 
Share this answer
 
Comments
Wendelius 30-Dec-11 15:20pm    
OP's comment:

tnx, but still it wont solve my problem, i think in the end i have to define a generic class parameter, and then pass delegate as parameter, and each method with input of t, if the t is correct, it will put it in method, else it will throw exeption,... i still write nothing about this one.

BTW, i'll wait till tommorow , i look for best way
Hello Hassan,

use interfaces instead of delegages (see below).

BTW: Delegates are often second choice, compared with interfaces.

Cheers

Andi




Minimalistic crypto interface:

C#
/// <summary>basic crypto interface</summary>
public interface ICryptoAlgorithm
{
    /// <summary>encrypt</summary>
    /// <param name="plainData">plain data bytes</param>
    /// <returns>encrypted data bytes</returns>
    byte[] Encrypt(byte[] plainData);
    /// <summary>decrypt</summary>
    /// <param name="encryptedData">encrypted data bytes</param>
    /// <returns>plain data bytes</returns>
    byte[] Decrypt(byte[] encryptedData);
}


Your own encapsulation of the specific crypto algorithm (implements ICryptoAlgorithm):

C#
public class MyCrypto: ICryptoAlgorithm
{
    TypeA _a;
    TypeB _b;
    public MyCrypto(TypeA a, TypeB b)
    {
       _a = a;
       _b = b;
       ...
    }

    public byte[] Encrypt(byte[] plainData)
    {
        // use a, b, etc.
        ...
    }

    public byte[] Decrypt(byte[] encryptedData)
    {
        // use a, b, etc.
        ...
    }
}


Your own function takes a concrete ICryptoAlgorithm (instead of a delegate):

C#
void Save(ICryptoAlgorithm alg, byte[] plainData)
{
    try
    {
        var encoded = alg.Encrypt(plainData);
        ...
    }
    catch (Exception exc)
    {
        Console.WriteLine(exc.ToString());
    }
}


Usage:

C#
ICryptoAlgorithm alg = new MyCrypto(x, y);
byte[] plainData = ...
Save(alg, plainData);
 
Share this answer
 
Comments
hassan faghihi 30-Dec-11 22:48pm    
this way i have to implement the interface in all the encryption method, yes, that's what I'll do.
but maybe some one wanna pass a new method to this... it wont perform using interface ?! isn't that right?
isn't delegate better in such a time?!
Andreas Gieriet 31-Dec-11 8:20am    
See my comment below...
Andreas Gieriet 31-Dec-11 4:24am    
I don't understand your statement above. Please give an example what you mean by this - you talk in too broad terms...

You can not do what you want by delegates - that's what the starategy pattern was inventet for. The strategy pattern similar to the described above is the way to do it.

You can not do a general-purpose-do-everything method: you have to decide what the purpose of the methods are. In your case I understand that you want to do some encryption/decryption but want to leave it open to the client to choose the algorithm. The only two methods you need for that are Encrypt/Decrypt. The client of you code has to provide an implementation for that interface. The algorithm-specific parameters are passed to that specific implementation before passing the object to your method. Please make your mind up by checking the strategy pattern as succested in Solution 1.
hassan faghihi 31-Dec-11 13:37pm    
Ok , think , i have multiple method with different signature:
like :
encodingA(string,int,enum):byte[]
encodingA(string,string,enum):byte[]
encodingA(string,string,string):byte[]
encodingA(string,int,enum):byte[]
Andreas Gieriet 1-Jan-12 9:37am    
You give so little info that I have a hard time to help you... :-(

Please give a full example with meaningful names so that one can give reasonable help.

What I can say:

1. A delegate defines a precise signature, therefore, you can only assign/pass a method with an exactly matching signature. I.e. you can not pass methods with varying signatures. Use the Strategy Patterns instead.

2. Reading you initial post, I come to the conclusion that you don't need to use delegates for the given problem. In you example, you can defined you method as

myMethod(byte[] b)
{ ... }


and then use the following:

byte[] data;
string skey;
...
byte[] b = AEncMethod(data,skey);
...
myMethod(b);


Does that make sense for you?

Cheers

Andi
 
Share this answer
 
Comments
hassan faghihi 30-Dec-11 22:51pm    
hey man,
1. this way again both mothod have same signature...
2. as i said i'm looking for something to use in .Net 2, which 'Func' class come within .Net 3.5
Ok, since delegate dosen't support multi-type input or atlast as i searched in internet, i solved this with Generics, so:

i define a delegate as

C#
public delegate byte[] EncryptMethod<t>(byte[] PlainToEnc, T t);</t>


which T is and entity class for the parameters

next i defaine my method as this:

C#
public static void WriteSerialize<T,E>(T entity, EncryptMethod<E> encryptMethod, E e, string fileAddress)
{


so in here T is the entity that u dont need to care about, it's just my data which will processing within my method, so u can remove it, if u dont have any entity data class,
but the 'E'
is Important, cause it's the Type we defined for out delegate in top,
so to provide a delegate that accept different values, you have to provide unknown type <t> (in here E) after you write your method name, like
C#
WriteSerialize<e> (...)</e>

and then as parameter, you need to pass That unknown type again to the delegate...., also you need to provide an object from that type
Like :
C#
(EncryptMethod<e> encryptMethod, E e)</e>


no one more step you have for implement this fully:

inside the method when u wanan call the delegate you write :
C#
encryptMethod.Invoke(e)

so u can pass any unknow input parameter to any delegate method...


after this the user who want to implement the delegate method have to go through this way:

1. he need to define all parameter which he need to change in his method.
like for DES encryption:
C#
public static byte[] Encrypt(byte[] plainData, string sKey, string iv, CipherMode cm, PaddingMode pm)
{

2. next the user need to define a class which contain all the input parameter, with public access to members, or public property with get attribute.
3. he use this class as input type for his method, the way he define his delegate
and call his method, within this method, and pass parameters to the method , he define in step 1.
like:
C#
public static byte[] Encrypt(byte[] PlainToEnc, DESParametersContainer DESPC)
{
    return Encrypt(PlainToEnc, DESPC.SKey, DESPC.IV, DESPC.Cipher, DESPC.Padding);
}

in here
DESParametersContainer
the class i defined

4. there's nothing left, jsut user have to call your method, with his method and instance of parameter data class.

C#
SerializeEncrypter.WriteSerialize<MyEntity, DESParametersContainer>(new MyEntity("a", "b", "c"), DESSymmetric.Encrypt, despc, DIR.GetCurrentDirectory() + fileName1);
 
Share this answer
 
Comments
Andreas Gieriet 5-Jan-12 13:00pm    
Reason for my vote 1: this is an overkill.
You try to enforce delegate usage where delegates are far off.
You introduce a parameter container - why don't you simply add the "Encrypt(byte[] b)" method to that "container" and you have the 1st half of the strategy pattern.
Define an interface that contains as only method the Encrypt method, the "container" must implement that interface - the 2nd part of the strategy pattern.
Finally, use that interface in your general WriteSerializer method. No need for any generics nor delegates.

Don't try to be smart on things that are established: the future maintainer of your code will thank you!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900