Click here to Skip to main content
15,885,278 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have a List of object because I will have diferent kind of classes (ex: Class1, Class2) and I don't know what the list will contains.

Then I have create for each class an extension method
(ex: public static Save(this Class1 c1) {})

As I have created an extension method for the list
(ex: public static Save(this List<object> lstObj) {})

The scenario is after filling the list with the object I call the extended Save() method of the list. In this method I need to loop through all the object and for foreach object I need to call the extented Save() method for it.

Any idea?
Posted
Updated 28-Sep-10 21:14pm
v2

I would recommend trying to solve this by having the Class1 and Class2 implement some sort of ISaveable interface instead, but if that can't be done then here's two different solutions.

The first one tries to find any matching extension method in the calling assembly, and the second one is slightly more efficient but forces you to specify the type owning the extension methods:

C#
public static class Extensions
{
    public static void Save(this A instance)
    {
        Console.WriteLine("Saving A");
    }
    public static void Save(this B instance)
    {
        Console.WriteLine("Saving B");
    }
    private static bool IsMethodOk(MethodInfo method, object obj)
    {
        return
            method.IsStatic
            &&
            method.GetParameters().Count() == 1
            &&
            method.GetParameters()[0].ParameterType == obj.GetType();
    }
    public static void Save1(this IList<object> list)
    {
        foreach (object obj in list)
        {
            foreach (Type type in Assembly.GetCallingAssembly().GetTypes())
            {
                bool hasSaved = false;
                foreach (MethodInfo method in type.GetMethods())
                {
                    if (IsMethodOk(method, obj))
                    {
                        method.Invoke(null, new[] { obj });
                        hasSaved = true;
                        break;
                    }
                }
                if (hasSaved)
                    break;
            }
        }
    }
    public static void Save2(this IList<object> list, Type extensionClass)
    {
        foreach (object obj in list)
        {
            foreach (MethodInfo method in extensionClass.GetMethods())
            {
                if (IsMethodOk(method, obj))
                {
                    method.Invoke(null, new[] { obj });
                    break;
                }
            }
        }
    }
}


Hope this helps,
Fredrik
 
Share this answer
 
Comments
ziadb86 29-Sep-10 5:32am    
Dear Fredik 10x for your comment, but it didn't worked for me.. I don't know what's wrong..!! In my solution the classes are created in a project and the extension methods are located in different project, I tried to located the extension methods in the same namespace but the problem remains.... any idea??
I have resolved my problem using the below code...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Namespace1;
using System.Reflection;
using System.Data.Linq;

namespace Namespace2
{
    public static class Extensions
    {
        public static void Save(this IList<object> list)
        {
            if (list.Count > 0)
            {
                Assembly thisAssembly = Assembly.GetExecutingAssembly();//Assembly containin the extension method
                int objCount = list.Count;
                object currentObj;
                Type currentType = list[0].GetType();
                for (int i = 0; i < objCount; i++)
                {
                    currentObj = list[i];

                    //Since the query will return an IEnumarable object so I must use the foreach loop
                    //although I only have one extension method
                    foreach (MethodInfo method in GetExtensionMethods(thisAssembly, currentType))
                    {
                        method.Invoke(null, new object[] { currentObj });
                    }
                }
            }
        }

        static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly, Type extendedType)
        {
            var query = from type in assembly.GetTypes()
                        where !type.IsGenericType && !type.IsNested
                        from method in type.GetMethods(BindingFlags.Static
                            | BindingFlags.Public | BindingFlags.NonPublic)
                        where method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false)
                        where method.GetParameters()[0].ParameterType == extendedType
                        select method;
            return query;
        }

        public static void Save(this Class1 c1)
        {
            Console.WriteLine("Saving C1");
        }
    }   
}
 
Share this answer
 

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