Amir133
Amir133

Reputation: 2692

How to create Dynamic Method?

I have a number of methods, each of which checks the same set of conditions and returns a null value if none of the conditions are met, otherwise returns an object of different classes. Is there a way to not have to write all of these terms for each function and use less code?

    public A methode1()
    {
        if ///something
            return A("xxx")
        else if ///something
            return A("yyy")
        else if ///something
            return A("zzzz")
        else 
            return Error() // or return null
    }
    public B methode2()
    {
        if ///something
            return B("mmmm")
        else if ///something
            return B("nnn")
        else if ///something
            return B("bbbb")
        else
            return Error() // or return null
    }

    public C methode3()
    {
        if ///something
            return C("oooo")
        else if ///something
            return C("ggg")
        else if ///something
            return C("llll")
        else
            return Error() // or return null
    }

Upvotes: 0

Views: 154

Answers (5)

Biju Kalanjoor
Biju Kalanjoor

Reputation: 552

According to your comment, I tried to rewrite your sample, hope this will help you. ask freely if you need more clarity.

class Program
{
    static void Main(string[] args)
    {
        var objFactory = new MyFactory();
        // Get and cast return object
        A a1= (A) objFactory.ConsolidatedMethod("Condition 1 for Objct A", "xxx");

        // Or Directly assian to base object
        IOutput a2 = objFactory.ConsolidatedMethod("Condition 2 for Objct A", "yyyy");

        // use anonymous object
        var b1= objFactory.ConsolidatedMethod("Condition 1 for Objct B", "mmmm");

        var nullcheck1 = objFactory.ConsolidatedMethod("null conditionj", "i'm null");
    }
}

interface IOutput
{
}

class A : IOutput
{
    public A(string objParam)
    {
    }
}

class B : IOutput
{
    public B(string objParam)
    {
    }
}

class NullOutput : IOutput
{
    public NullOutput(string objParam)
    {
    }
}

class MyFactory
{
    /// <summary>
    /// Demo 
    /// </summary>
    /// <param name="arg">you can use this based on your requirement </param>
    /// <param name="objparam">you can use this based on your requirement </param>
    /// <returns>IOutput</returns>
    public IOutput ConsolidatedMethod(string arg, string objparam)
    {
        IOutput _output=default;

        if (arg == "Condition 1 for Objct A")
            _output = new A(objparam);
        else if (arg == "Condition 2 for Objct A")
            _output = new A(objparam);
        else if (arg == "Condition 1 for Objct b")
            _output = new B(objparam);
        else if (arg == "Condition 2 for Objct B")
            _output = new B(objparam);
        else
            _output = new NullOutput(objparam);

        return _output;
    }
}

Upvotes: 0

Guru Stron
Guru Stron

Reputation: 141690

You can combine template method pattern with generics:

public abstract class AbstractTemplate<T>
{
    public T methode()
    {
        if ///something
            return Do1();
        else if ///something
            return Do2();
        else if ///something
            return Do3();
        else 
            return Error() // or return null
    }
    protected abstract T Do1();
    protected abstract T Do2();
    protected abstract T Do3();
}

public class ConcreteATemplate : AbstractTemplate<A>
{
    protected override T Do1() => A("xxx");
    protected override T Do2() => A("yyy");
    protected override T Do3() => A("zzzz");
}

And use it inside your methods:

public A methode1() => new ConcreteATemplate().methode(); // also can "cache" instance in your case in static readonly field.

Upvotes: 1

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112279

You could use a method with a generic type parameter and a set of initial values.

private T GetIfOkay<T>(string a, string b, string c)
    where T : new()
{
    if (something)
        return new T(a);
    else if (something else)
        return new T(b);
    else if (yet something else)
        return new T(c);
    else
        return null;
}

public A methode1()
{
    return GetIfOkay<A>("xxx", "yyy", "zzzz");
}

public B methode2()
{
    return GetIfOkay<B>("mmmm", "nnn", "bbbb");
}

// etc.

If you need a more dynamic behaviour, @donggas90's solution.

See:

Upvotes: 0

Biju Kalanjoor
Biju Kalanjoor

Reputation: 552

Standard approch is , you can use a factory class with interface/abstract class

public interface IOutput {
}
public class Output1 : IOutput{
}
public class Output2 : IOutput{
}
public class MyFactory
{
    public IOutput Get()// add args list of any
    {
       if(condition) // you can use args in condition if necessary
           return new Output1();
       else
           return new Output2();
    }
}

Upvotes: 1

Pias Uddin Jibon
Pias Uddin Jibon

Reputation: 109

You can use generic method and repository pattern. Here is a generic method example with C#. I think it may give you some idea..

public static async Task<List<ObjectType>> GetDataList<ObjectType>(UserAuthorization token) where ObjectType : BaseModel
        {
            List<ObjectType> data = new List<ObjectType>();
            try
            {
                if(token.UserTypes.Count > 0)
                {
                    Type genericClass = typeof(Repository<>);
                    Type constructedClass = genericClass.MakeGenericType(typeof(ObjectType));
                    MERPDbContext mERPContext = new MERPDbContext();
                    var created = (Repository<ObjectType>)Activator.CreateInstance(constructedClass, mERPContext);
                    if (token.UserTypes[0].Id == (byte)UserTypes.SuperAdmin)
                    {
                        var sub = await created.GetAsync();
                        data = sub.ToList();
                    }
                    else if (token.UserTypes[0].Id == (byte)UserTypes.InstituteAdmin)
                    {
                        data = await created.FilterListAsync
                                            (x => x.InstituteId == token.InstituteID);
                    }
                    else
                    {
                        data = await created.FilterListAsync(x =>
                                            x.InstituteId == token.InstituteID && x.CampusId == token.CampusID);
                    }
                }
            }
            catch (Exception e)
            {
                
            }
            return data;
        }

Upvotes: 0

Related Questions