如何创建动态方法?

huangapple go评论130阅读模式
英文:

How to create Dynamic Method?

问题

  1. 我有一些方法,每个方法都检查相同的一组条件,如果条件都不满足,则返回null值,否则返回不同类的对象。
  2. 有没有办法不必为每个函数都写这些条件,减少代码量?
  3. public A methode1()
  4. {
  5. if ///something
  6. return A("xxx")
  7. else if ///something
  8. return A("yyy")
  9. else if ///something
  10. return A("zzzz")
  11. else
  12. return Error() // 或者返回null
  13. }
  14. public B methode2()
  15. {
  16. if ///something
  17. return B("mmmm")
  18. else if ///something
  19. return B("nnn")
  20. else if ///something
  21. return B("bbbb")
  22. else
  23. return Error() // 或者返回null
  24. }
  25. public C methode3()
  26. {
  27. if ///something
  28. return C("oooo")
  29. else if ///something
  30. return C("ggg")
  31. else if ///something
  32. return C("llll")
  33. else
  34. return Error() // 或者返回null
  35. }
英文:

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?

  1. public A methode1()
  2. {
  3. if ///something
  4. return A("xxx")
  5. else if ///something
  6. return A("yyy")
  7. else if ///something
  8. return A("zzzz")
  9. else
  10. return Error() // or return null
  11. }
  12. public B methode2()
  13. {
  14. if ///something
  15. return B("mmmm")
  16. else if ///something
  17. return B("nnn")
  18. else if ///something
  19. return B("bbbb")
  20. else
  21. return Error() // or return null
  22. }
  23. public C methode3()
  24. {
  25. if ///something
  26. return C("oooo")
  27. else if ///something
  28. return C("ggg")
  29. else if ///something
  30. return C("llll")
  31. else
  32. return Error() // or return null
  33. }

答案1

得分: 1

标准方法是,您可以使用带有接口/抽象类的工厂类。

  1. public interface IOutput {
  2. }
  3. public class Output1 : IOutput{
  4. }
  5. public class Output2 : IOutput{
  6. }
  7. public class MyFactory
  8. {
  9. public IOutput Get()// 添加任何参数列表
  10. {
  11. if(条件) // 如果必要,可以在条件中使用参数
  12. return new Output1();
  13. else
  14. return new Output2();
  15. }
  16. }
英文:

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

  1. public interface IOutput {
  2. }
  3. public class Output1 : IOutput{
  4. }
  5. public class Output2 : IOutput{
  6. }
  7. public class MyFactory
  8. {
  9. public IOutput Get()// add args list of any
  10. {
  11. if(condition) // you can use args in condition if necessary
  12. return new Output1();
  13. else
  14. return new Output2();
  15. }
  16. }

答案2

得分: 1

你可以将模板方法模式泛型结合使用:

  1. public abstract class AbstractTemplate<T>
  2. {
  3. public T Method()
  4. {
  5. if ///something
  6. return Do1();
  7. else if ///something
  8. return Do2();
  9. else if ///something
  10. return Do3();
  11. else
  12. return Error(); // 或者返回 null
  13. }
  14. protected abstract T Do1();
  15. protected abstract T Do2();
  16. protected abstract T Do3();
  17. }
  18. public class ConcreteATemplate : AbstractTemplate<A>
  19. {
  20. protected override A Do1() => A("xxx");
  21. protected override A Do2() => A("yyy");
  22. protected override A Do3() => A("zzzz");
  23. }
  24. 然后在你的方法中使用它:
  25. ```csharp
  26. public A Method1() => new ConcreteATemplate().Method(); // 也可以在你的情况下“缓存”实例在静态 readonly 字段中。
  27. [1]: https://en.wikipedia.org/wiki/Template_method_pattern
  28. [2]: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/
英文:

You can combine template method pattern with generics:

  1. public abstract class AbstractTemplate&lt;T&gt;
  2. {
  3. public T methode()
  4. {
  5. if ///something
  6. return Do1();
  7. else if ///something
  8. return Do2();
  9. else if ///something
  10. return Do3();
  11. else
  12. return Error() // or return null
  13. }
  14. protected abstract T Do1();
  15. protected abstract T Do2();
  16. protected abstract T Do3();
  17. }
  18. public class ConcreteATemplate : AbstractTemplate&lt;A&gt;
  19. {
  20. protected override T Do1() =&gt; A(&quot;xxx&quot;);
  21. protected override T Do2() =&gt; A(&quot;yyy&quot;);
  22. protected override T Do3() =&gt; A(&quot;zzzz&quot;);
  23. }

And use it inside your methods:

  1. public A methode1() =&gt; new ConcreteATemplate().methode(); // also can &quot;cache&quot; instance in your case in static readonly field.

答案3

得分: 0

你可以使用具有通用类型参数和一组初始值的方法。

  1. private T GetIfOkay<T>(string a, string b, string c)
  2. where T : new()
  3. {
  4. if (something)
  5. return new T(a);
  6. else if (something else)
  7. return new T(b);
  8. else if (yet something else)
  9. return new T(c);
  10. else
  11. return null;
  12. }
  13. public A methode1()
  14. {
  15. return GetIfOkay<A>("xxx", "yyy", "zzzz");
  16. }
  17. public B methode2()
  18. {
  19. return GetIfOkay<B>("mmmm", "nnn", "bbbb");
  20. }
  21. // etc.

如果需要更动态的行为,可以参考 @donggas90 的解决方案。

参见:

英文:

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

  1. private T GetIfOkay&lt;T&gt;(string a, string b, string c)
  2. where T : new()
  3. {
  4. if (something)
  5. return new T(a);
  6. else if (something else)
  7. return new T(b);
  8. else if (yet something else)
  9. return new T(c);
  10. else
  11. return null;
  12. }
  13. public A methode1()
  14. {
  15. return GetIfOkay&lt;A&gt;(&quot;xxx&quot;, &quot;yyy&quot;, &quot;zzzz&quot;);
  16. }
  17. public B methode2()
  18. {
  19. return GetIfOkay&lt;B&gt;(&quot;mmmm&quot;, &quot;nnn&quot;, &quot;bbbb&quot;);
  20. }
  21. // etc.

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

See:

答案4

得分: 0

你可以使用通用方法和仓储模式。以下是一个使用C#的通用方法示例,我认为它可能会给你一些想法:

  1. public static async Task<List<ObjectType>> GetDataList<ObjectType>(UserAuthorization token) where ObjectType : BaseModel
  2. {
  3. List<ObjectType> data = new List<ObjectType>();
  4. try
  5. {
  6. if (token.UserTypes.Count > 0)
  7. {
  8. Type genericClass = typeof(Repository<>);
  9. Type constructedClass = genericClass.MakeGenericType(typeof(ObjectType));
  10. MERPDbContext mERPContext = new MERPDbContext();
  11. var created = (Repository<ObjectType>)Activator.CreateInstance(constructedClass, mERPContext);
  12. if (token.UserTypes[0].Id == (byte)UserTypes.SuperAdmin)
  13. {
  14. var sub = await created.GetAsync();
  15. data = sub.ToList();
  16. }
  17. else if (token.UserTypes[0].Id == (byte)UserTypes.InstituteAdmin)
  18. {
  19. data = await created.FilterListAsync(x => x.InstituteId == token.InstituteID);
  20. }
  21. else
  22. {
  23. data = await created.FilterListAsync(x =>
  24. x.InstituteId == token.InstituteID && x.CampusId == token.CampusID);
  25. }
  26. }
  27. }
  28. catch (Exception e)
  29. {
  30. }
  31. return data;
  32. }

请注意,这是提供给你的通用方法示例,具体的实现可能需要根据你的应用程序需求进行调整。

英文:

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

  1. public static async Task&lt;List&lt;ObjectType&gt;&gt; GetDataList&lt;ObjectType&gt;(UserAuthorization token) where ObjectType : BaseModel
  2. {
  3. List&lt;ObjectType&gt; data = new List&lt;ObjectType&gt;();
  4. try
  5. {
  6. if(token.UserTypes.Count &gt; 0)
  7. {
  8. Type genericClass = typeof(Repository&lt;&gt;);
  9. Type constructedClass = genericClass.MakeGenericType(typeof(ObjectType));
  10. MERPDbContext mERPContext = new MERPDbContext();
  11. var created = (Repository&lt;ObjectType&gt;)Activator.CreateInstance(constructedClass, mERPContext);
  12. if (token.UserTypes[0].Id == (byte)UserTypes.SuperAdmin)
  13. {
  14. var sub = await created.GetAsync();
  15. data = sub.ToList();
  16. }
  17. else if (token.UserTypes[0].Id == (byte)UserTypes.InstituteAdmin)
  18. {
  19. data = await created.FilterListAsync
  20. (x =&gt; x.InstituteId == token.InstituteID);
  21. }
  22. else
  23. {
  24. data = await created.FilterListAsync(x =&gt;
  25. x.InstituteId == token.InstituteID &amp;&amp; x.CampusId == token.CampusID);
  26. }
  27. }
  28. }
  29. catch (Exception e)
  30. {
  31. }
  32. return data;
  33. }

答案5

得分: 0

根据您的评论,我尝试重新编写您的示例,希望这能帮助您。如果需要更多明确信息,请随时提问。

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. var objFactory = new MyFactory();
  6. // 获取并强制转换返回对象
  7. A a1 = (A)objFactory.ConsolidatedMethod("Condition 1 for Objct A", "xxx");
  8. // 或直接分配给基础对象
  9. IOutput a2 = objFactory.ConsolidatedMethod("Condition 2 for Objct A", "yyyy");
  10. // 使用匿名对象
  11. var b1 = objFactory.ConsolidatedMethod("Condition 1 for Objct B", "mmmm");
  12. var nullcheck1 = objFactory.ConsolidatedMethod("null conditionj", "i'm null");
  13. }
  14. }
  15. interface IOutput
  16. {
  17. }
  18. class A : IOutput
  19. {
  20. public A(string objParam)
  21. {
  22. }
  23. }
  24. class B : IOutput
  25. {
  26. public B(string objParam)
  27. {
  28. }
  29. }
  30. class NullOutput : IOutput
  31. {
  32. public NullOutput(string objParam)
  33. {
  34. }
  35. }
  36. class MyFactory
  37. {
  38. /// <summary>
  39. /// 演示
  40. /// </summary>
  41. /// <param name="arg">根据您的需求使用此参数</param>
  42. /// <param name="objparam">根据您的需求使用此参数</param>
  43. /// <returns>IOutput</returns>
  44. public IOutput ConsolidatedMethod(string arg, string objparam)
  45. {
  46. IOutput _output = default;
  47. if (arg == "Condition 1 for Objct A")
  48. _output = new A(objparam);
  49. else if (arg == "Condition 2 for Objct A")
  50. _output = new A(objparam);
  51. else if (arg == "Condition 1 for Objct B")
  52. _output = new B(objparam);
  53. else if (arg == "Condition 2 for Objct B")
  54. _output = new B(objparam);
  55. else
  56. _output = new NullOutput(objparam);
  57. return _output;
  58. }
  59. }
英文:

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

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. var objFactory = new MyFactory();
  6. // Get and cast return object
  7. A a1= (A) objFactory.ConsolidatedMethod(&quot;Condition 1 for Objct A&quot;, &quot;xxx&quot;);
  8. // Or Directly assian to base object
  9. IOutput a2 = objFactory.ConsolidatedMethod(&quot;Condition 2 for Objct A&quot;, &quot;yyyy&quot;);
  10. // use anonymous object
  11. var b1= objFactory.ConsolidatedMethod(&quot;Condition 1 for Objct B&quot;, &quot;mmmm&quot;);
  12. var nullcheck1 = objFactory.ConsolidatedMethod(&quot;null conditionj&quot;, &quot;i&#39;m null&quot;);
  13. }
  14. }
  15. interface IOutput
  16. {
  17. }
  18. class A : IOutput
  19. {
  20. public A(string objParam)
  21. {
  22. }
  23. }
  24. class B : IOutput
  25. {
  26. public B(string objParam)
  27. {
  28. }
  29. }
  30. class NullOutput : IOutput
  31. {
  32. public NullOutput(string objParam)
  33. {
  34. }
  35. }
  36. class MyFactory
  37. {
  38. /// &lt;summary&gt;
  39. /// Demo
  40. /// &lt;/summary&gt;
  41. /// &lt;param name=&quot;arg&quot;&gt;you can use this based on your requirement &lt;/param&gt;
  42. /// &lt;param name=&quot;objparam&quot;&gt;you can use this based on your requirement &lt;/param&gt;
  43. /// &lt;returns&gt;IOutput&lt;/returns&gt;
  44. public IOutput ConsolidatedMethod(string arg, string objparam)
  45. {
  46. IOutput _output=default;
  47. if (arg == &quot;Condition 1 for Objct A&quot;)
  48. _output = new A(objparam);
  49. else if (arg == &quot;Condition 2 for Objct A&quot;)
  50. _output = new A(objparam);
  51. else if (arg == &quot;Condition 1 for Objct b&quot;)
  52. _output = new B(objparam);
  53. else if (arg == &quot;Condition 2 for Objct B&quot;)
  54. _output = new B(objparam);
  55. else
  56. _output = new NullOutput(objparam);
  57. return _output;
  58. }
  59. }

huangapple
  • 本文由 发表于 2020年8月11日 23:07:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63361066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定