February 2008 - Posts

Yield in c#
Monday, February 25, 2008 3:47 AM

i've been trying to explain the keyword yield to a friend of mine for more than an hour and he did not get it.

but finally when i typed in this example he finally did

   1: class enu :IEnumerable
   2:   {
   3:       public IEnumerator GetEnumerator()
   4:       {
   5:           yield return 1;
   6:           yield return 2;
   7:           yield return 3;
   8:       }
   9:   }

 

it actually means that when you are enumerating this object it will return a different value/object on every iteration

so the next time i revised this sample it was way easier to grasp the multiple returns

   1: public class enu :IEnumerable
   2:  {
   3:      int _index=0;
   4:      int[] numbers = { 1, 2, 3, 4, 5 };
   5:      public IEnumerator GetEnumerator()
   6:      {
   7:          yield return numbers[_index];
   8:          _index++;
   9:      }
  10:  }

 

now that i've gone this far i have to say that the enumerator here returns are not of a specific type nothing in the previous code specifies that the return type is an int

so..

after C# 2.0 has introduced generics this would work fine

 

   1: public class enu :IEnumerable<int>
   2:  {
   3:      int _index=0;
   4:      int[] numbers = { 1, 2, 3, 4, 5 };
   5:      public IEnumerator GetEnumerator()
   6:      {
   7:          yield return numbers[_index];
   8:          _index++;
   9:      }
  10:  
  11:      IEnumerator<int> IEnumerable<int>.GetEnumerator()
  12:      {
  13:          yield return numbers[_index];
  14:          _index++;
  15:      }
  16:  }

 

note that this new Interface IEnumerable<T> needs both methods to be implemented

by amir.magdy | 15 comment(s)
Filed under: ,
Delegates to LINQ [passing logic as a parameter] (part I)
Friday, February 08, 2008 9:03 AM

it's normal to pass data to a function just thow in a parameter of the type of data you want to pass and ur set

public int add (int i,int u ){
    return i+u;
}

 

now think in a different way, u now want to build a set of operations that the user can choose from now what you need is to build a function that would take the user's input and the operation as parameters and put them together...

for instance he has a set of .. customers if you will and he wants to have them filtered in predefined filters like valuable customers , local customers and new customer.

Data that we're using looks like this

public class Customer {
    public int Id{ get; set;};
    public string Name{ get; set;};
    public DateTime FirstPurchaseDate{ get; set;};
    public string city{get; set;};
    public decimal TotalPurchase {get; set;}
}

we'll be passing that customer in a list of type customer

var customerList= new List<Customer>();

now for the logic, how to implement the three requested filter in a way they can be sent as a parameter to the search Method, well this is how it's done:

1-to do that we think of a way that we can reference a logic (a method) which is a delegate. So we'll build a delegate that can receive a Customer as a parameter and return weather it's valid customer according to the required criteria so the delegate's declaration should look something like this

public delegate bool evaluatetorDelegate(Customer customer);

 

2- we need to build a function that will actually do the evaluation but to do that it will have to have the same signature as the delegate; here we'll implement the three simple required functions

private const string LOCAL_CITY ="Alexandria"; //my city in Egypt :D
private const decimal VALUABLE_CUSTOMER_LIMIT = 10000.00;
 
public bool IsValuableCustomer(Customer customer){
    return customer.TotalPurchase > VALUABLE_CUSTOMER_LIMIT;
}
 
public bool IsLocalCustomer(Customer customer){
    return customer.City == LOCAL_CITY ;
}
 
public bool IsNewCustomer(Customer customer){
    return customer.FirstPurchaseDate > DateTime.ToDay.AddMonth(-1);
}

 

3- now we need to implement the function that will actually apply the filtering; should also  look something like this

public List<Customer> executeFilter(List<Customer> customers,
                                         evaluatetorDelegate filter) {
    List<Customer> resultList = List<Customer>();
    foreach (Customer customer in customers)
    {
        if (filter.Invoke(customer))
            resultList.Add(customer);
    }
    return resultList;
}

 

4- now that the example is complete let's see how can we utilize this code

public static void main(string param){}{
switch (param){
    case 1:
    evaluatetorDelegate d = IsLocalCustomer;
    break;
    case 2:
    evaluatetorDelegate d = IsNewCustomer;
    break;
    case 3:
    evaluatetorDelegate d = IsValuableCustomer;
    break;
}
List<Customers> Customers= GetCustomersFromDB ()// :D
// and then we call the method 
//then we apply the filtering we need
 
Customers = executeFilter (Customers,d);
 
// now the Customers contain only the customers which meet the criteria.
by amir.magdy | 3 comment(s)
Filed under: ,