代码之家  ›  专栏  ›  技术社区  ›  Lior Bruder

如何编写一个通用函数来调用具有特定类的通用函数?

  •  0
  • Lior Bruder  · 技术社区  · 7 年前

    我的代码:

    public class BaseParamsClass
    {
        public BaseParamsClass(int pBaseParam = 0)
        {
            baseParam = pBaseParam;
        }
    
        public int baseParam;
    }
    
    public class Parent1ParamsClass : BaseParamsClass
    {
        public Parent1ParamsClass(int pBaseParam = 0) : base(pBaseParam)
        {
    
        }
    
        public int parentParam1;
    }
    
    public class Parent2ParamsClass : BaseParamsClass
    {
        public Parent2ParamsClass(int pBaseParam = 0) : base(pBaseParam)
        {
    
        }
    
        public int parentParam2;
    }
    
    public delegate void Parent1Callback(Parent1ParamsClass theParams);
    public delegate void Parent2Callback(Parent2ParamsClass theParams);
    
    private IEnumerator CoRFunction1(Parent1Callback parent1Callback)
    {
        // This demonstrate few actions i do before the call
        yield return new WaitForSeconds(1);
    
        // Now i get the result, it can be 0-10, each one should activate different callback
        int result = 0;
    
        parent1Callback(new Parent1ParamsClass(0));
    }
    
    private IEnumerator CoRFunction2(Parent2Callback parent2Callback)
    {
        // This demonstrate few actions i do before the call
        yield return new WaitForSeconds(1);
    
        // Now i get the result, it can be 0-10, each one should activate different callback
        int result = 0;
    
        // Need a generic way to do the next line:
        parent2Callback(new Parent2ParamsClass(0));
    }
    
    private IEnumerator CoRFunction2(Parent2Callback parent2Callback)
    {
        // This demonstrate few actions i do before the call
        yield return new WaitForSeconds(1);
    
        // Now i get the result, it can be 0-10, each one should activate different callback
        int result = 0;
    
        // Need a generic way to do the next line:
        parent2Callback(new Parent2ParamsClass(0));
    }
    

    我需要的是替换“//需要a…”后面的行的方法在更一般的情况下,最后两个函数应该是这样的:

    private IEnumerator CoRFunction1(Parent1Callback parent1Callback)
    {
        // This demonstrate few actions i do before the call
        yield return new WaitForSeconds(1);
    
        // Now i get the result, it can be 0-10, each one should activate different callback
        int result = 0;
    
        genericFunction<Parent1Callback>(Parent1ParamsClass);
    }
    
    private IEnumerator CoRFunction2(Parent2Callback parent2Callback)
    {
        // This demonstrate few actions i do before the call
        yield return new WaitForSeconds(1);
    
        // Now i get the result, it can be 0-10, each one should activate different callback
        int result = 0;
    
        genericFunction<Parent2Callback>(Parent2ParamsClass);
    }
    

    如何创建“genericFunction”有什么想法吗?

    2 回复  |  直到 7 年前
        1
  •  1
  •   GPW    7 年前

    我评论道-现在还不太清楚你到底想要实现什么,我怀疑你可以用一种比你想要的更好的方式来实现。。。但我要说的是 认为 下面这样的方法可能会奏效。

    更改基参数类,使您不必依赖构造函数来设置其内部字段,然后将一些泛型方法仅约束为基类型,这样您最终会遇到这种情况:

    public class BaseParamsClass
    {
        public virtual void SetParam(int pBaseParam)
        {
            baseParam = 0;
        }
    
        public int baseParam;
    }
    
    public class Parent1ParamsClass : BaseParamsClass
    {
        public override void SetParam(int pBaseParam)
        {
            base.SetParam(pBaseParam);
            //do other stuff specific to this class...
        }
        public int parentParam1;
    }
    
    public class Parent2ParamsClass : BaseParamsClass
    {
        public override void SetParam(int pBaseParam)
        {
            base.SetParam(pBaseParam);
            //do other stuff specific to this class...
        }
    
        public int parentParam2;
    }
    
    
    public delegate void GenericCallback<T>(T theParams) where T : BaseParamsClass, new();
    
    private IEnumerator GenericCorFunction<T>(GenericCallback<T> callback) where T:BaseParamsClass, new()
    {
        // This demonstrate few actions i do before the call
        yield return new WaitForSeconds(1);
    
        // Now i get the result, it can be 0-10, each one should activate different callback
        int result = 0;
    
        //I assume you want result here.
        //Also note that you can't use the constructor to set the base param as at compile time
        //we're not sure which type will be being used.  There are ways around this but it's
        //probably clearer to use basic constructor then call the SetParam virtual/overridden method            
        var param = new T();
        param.SetParam(result);
        callback(param);
    }
    

    您可以这样使用它:

    var newEnumerator = GenericCorFunction<Parent2ParamsClass>(p =>
    {
        //this is the callback function body.  This will only run when 
        //called at the end of the GenericCorFunction
        //Do things with p, which will be a PArent2ParamsClass object
        //with its baseParam field set to whatever result was.
        if (p.baseParam == 3)
        {
            throw new NotImplementedException();
        }
    });
    
    //do stuff with newEnumerator...
    
        2
  •  1
  •   Mong Zhu Bart de Boer    7 年前

    另一种方法是 Activator.CreateInstance 。这将允许您绕过 new() 限制并使用已编写的构造函数:

    public delegate void ParentCallback<T>(T theParams) where T : BaseParamsClass;
    
    private void CoRFunction<T>(ParentCallback<T> parentCallback) where T : BaseParamsClass
    {    
        // Now i get the result, it can be 0-10, each one should activate different callback
        int result = 0;
    
        parentCallback((T)Activator.CreateInstance(typeof(T), 11));
    }
    

    (我将其更改为无效,以使其可供我测试)

    下面是测试代码和我用来测试它的调用:

    public void Call_1(Parent1ParamsClass par1)
    {
        Console.WriteLine("CALL 1 baseParam: " + par1.baseParam);
    }
    
    public void Call_2(Parent2ParamsClass par2)
    {
        Console.WriteLine("CALL 2 baseParam: " + par2.baseParam);
    }
    

    电话:

    CoRFunction<Parent1ParamsClass>(Call_1);
    CoRFunction<Parent2ParamsClass>(Call_2);
    

    输出:

    调用1 baseParam:11
    调用2 baseParam:11