CSharp delegate

User avatar
agibsonsw
SilverLounger
Posts: 2403
Joined: 05 Feb 2010, 22:21
Location: London ENGLAND

CSharp delegate

Post by agibsonsw »

Hello. I don't know if anybody has experience of C# and delegates? The following code works, but it's not a correct implementation:

Code: Select all

using System;
namespace UseDelegate
{
	public delegate decimal CalculateFee (decimal balance);
	
	public class Account
	{
		public decimal RipOffFee(decimal bal)
		{
			return 100;
		}
		public decimal FriendlyFee(decimal bal)
		{
			return 10;
		}
	}
	class Program
	{
		public static void Main(string[] args)
		{
			Account ac = new Account();
			CalculateFee calc = new CalculateFee(ac.RipOffFee);
			Console.WriteLine("Fee is " + calc(200).ToString());
			calc = new CalculateFee (ac.FriendlyFee);
			Console.WriteLine("Fee is " + calc(200).ToString());
			Console.Write("Press any key to continue . . . ");
			Console.ReadKey(true);
		}
	}
}
The calc() method always applies to the Account named ac. I should have to enter 'ac.calc()' so that the calc() method is applied for a particular object.
How can I re-write this correctly? Thanks, Andy.
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.

User avatar
HansV
Administrator
Posts: 78549
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: CSharp delegate

Post by HansV »

C# :flee: :hiding:
Best wishes,
Hans

User avatar
agibsonsw
SilverLounger
Posts: 2403
Joined: 05 Feb 2010, 22:21
Location: London ENGLAND

Re: CSharp delegate

Post by agibsonsw »

I thought that might be the reaction..
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.

User avatar
agibsonsw
SilverLounger
Posts: 2403
Joined: 05 Feb 2010, 22:21
Location: London ENGLAND

Re: CSharp delegate

Post by agibsonsw »

I've tried another forum, but this is the best one!
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.

User avatar
Charlotte
Her Majesty
Posts: 499
Joined: 19 Jan 2010, 07:13

Re: CSharp delegate

Post by Charlotte »

agibsonsw wrote:Hello. I don't know if anybody has experience of C# and delegates? The following code works, but it's not a correct implementation:

The calc() method always applies to the Account named ac. I should have to enter 'ac.calc()' so that the calc() method is applied for a particular object.
How can I re-write this correctly? Thanks, Andy.
The code works but it doesn't? :scratch: It doesn't really matter whether it's C# or VB, the same logic applies.

you create a new instance of the Account class in this line

Code: Select all

Account ac = new Account();
and use it here

Code: Select all

        CalculateFee calc = new CalculateFee(ac.RipOffFee);
to call the delegate, but you're calling it to pass itself. A delegate is a method for passing arguments into a routine that requires them. You're going around in circles, so I don't understand what this is supposed to do:

Code: Select all

         CalculateFee calc = new CalculateFee(ac.RipOffFee);
         Console.WriteLine("Fee is " + calc(200).ToString());

Is calc a method of an underlying call (that sinks the delegate), or what? It looks like you're using it as two different things. Ordinarily you would simply call the delegate, not try and set its value by calling it with an argument.
Charlotte

User avatar
agibsonsw
SilverLounger
Posts: 2403
Joined: 05 Feb 2010, 22:21
Location: London ENGLAND

Re: CSharp delegate

Post by agibsonsw »

I did re-write it to the following version which I believe works, unless I've misunderstood the concept?

Code: Select all

using System;
namespace UseDelegate
{
	public class Account
	{
		private delegate decimal CalculateFee (decimal balance);
		private CalculateFee calc;
		private decimal balance;
		
		private decimal RipOffFee(decimal bal)
		{
			return 100;
		}
		private decimal FriendlyFee(decimal bal)
		{
			return 10;
		}
		public Account(bool standardAc, decimal openingBal)
		{
			this.balance = openingBal;
			if (standardAc)
				this.calc = new CalculateFee(RipOffFee);
			else
				this.calc= new CalculateFee(FriendlyFee);
		}
		public decimal Trans(decimal amt)
		{
			this.balance = this.balance + amt;
			if (amt < 0)
				this.balance = this.balance - this.calc(amt);
			return balance;
		}
	}
	class Program
	{
		public static void Main(string[] args)
		{
			Account ac = new Account(true, 500);
			Console.WriteLine("Balance after withdrawing £100 is " + ac.Trans(-100).ToString());
		}
	}
}
The way I understand it is, if someone opens a standard account then every time they make a withdrawal the fee is calculated with the delegated method 'RipOffFee'. If it's not a standard account then the fee is calculated differently (delegated to 'FriendlyFee').
So if they change the type of account all I would need to do would be to delegate to the appropriate 'calc' method, and this would all be hidden from the interface.
This is just a code fragment, but have I understood the concept and implemented it in a reasonable way? Thanks, Andy.
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.

User avatar
Charlotte
Her Majesty
Posts: 499
Joined: 19 Jan 2010, 07:13

Re: CSharp delegate

Post by Charlotte »

I'm a VB.Net programmer rather than C#, so I could overlook something in your code. I am baffled by this line

Code: Select all

      private CalculateFee calc;
 
Are you declaring the Calc method of the class represented by the delegate?

:sorry: but that's the best I can do for you on C#. :heavy:
Charlotte

User avatar
agibsonsw
SilverLounger
Posts: 2403
Joined: 05 Feb 2010, 22:21
Location: London ENGLAND

Re: CSharp delegate

Post by agibsonsw »

Code: Select all

private delegate decimal CalculateFee (decimal balance);     // declares a delegate type
private CalculateFee calc;    // creates an instance of the delegate

this.calc = new CalculateFee(RipOffFee);   // assigns a method AS the delegate
I believe all of this code is required. I have to define the delegate's 'behaviour', create an instance of the delegate and then assign a method to the instance.

Perhaps I should assume that I've got this correct :clapping:

Thanks for your assistance anyway. Andy.
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.

User avatar
Charlotte
Her Majesty
Posts: 499
Joined: 19 Jan 2010, 07:13

Re: CSharp delegate

Post by Charlotte »

I'm afraid you're on your own. I haven't yet worked with VS 2010, so I'm not sure if delegates have changed in VB, but in 2008, we generally used them a bit differently from your approach.
Charlotte

User avatar
agibsonsw
SilverLounger
Posts: 2403
Joined: 05 Feb 2010, 22:21
Location: London ENGLAND

Re: CSharp delegate

Post by agibsonsw »

That's okay, I feel fairly confident that I've grasped this concept.

A delegate is effectively a pointer to a function/method. The method itself must conform to the signature defined by the delegate.

It's often used to create custom events within a class, although I don't fully understand this process (as yet).

I've struggled to find a good explanation of delegates but just discovered this page that looks good:
http://www.c-sharpcorner.com/UploadFile ... gates.aspx

Thanks. Andy.
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.

User avatar
Charlotte
Her Majesty
Posts: 499
Joined: 19 Jan 2010, 07:13

Re: CSharp delegate

Post by Charlotte »

agibsonsw wrote:That's okay, I feel fairly confident that I've grasped this concept.

A delegate is effectively a pointer to a function/method. The method itself must conform to the signature defined by the delegate.
I've always viewed it the other way around, that the delegate has to match the method signature. :cheers:
Charlotte