使用模板方法替代重复的代码

4

我有4个方法,它们的代码相似

private void LogExceptions(ObjA.Input input, int customerId)
{
    //ObjA is a big object, thats why I try not to send the whole object in this method
    Log(input);
    Log(ObjA.Exceptions);
}

private void LogExceptions(ObjB.Input input, int customerId)
{
    //ObjB is a big object, thats why I try not to send the whole object in this method
    Log(input);
    Log(ObjB.Exceptions);
}

等等

我无法将它变成模板方法,比如

private void LogExceptions<T1,T2>(T1 input, int customerId) whereas     T1:ObjA.Input,ObjB.Input
{
    Log(T1);
    Log(T2);
}

如何做或者有其他方法吗?非常感谢您的帮助。

我认为我的问题无法得到正确的答案......这是精确的代码....

    private void LogExceptions(AccARef.Response response)
    {
        StringBuilder sbErrors = null;

        if (response.ValMethod != null && response.ValMethod.IsValid == false)
        {
            if (response.ValMethod.Errors.Count() > 0)
            {
                sbErrors = new StringBuilder();
                foreach (AccARef.Exception exp in response.ValMethod.Errors)
                {
                    sbErrors.Append(" * " + exp.Message + exp.StackTrace + " ");
                    Console.WriteLine(strError.ToString())
                }
            }
        }
    }

    private void LogExceptions(AccBRef.Response response)
    {
        StringBuilder sbErrors = null;

        if (response.ValMethod != null && response.ValMethod.IsValid == false)
        {
            if (response.ValMethod.Errors.Count() > 0)
            {
                sbErrors = new StringBuilder();
                foreach (AccBRef.Exception exp in response.ValMethod.Errors)
                {
                    sbErrors.Append(" * " + exp.Message + exp.StackTrace + " ");
                    Console.WriteLine(strError.ToString())
                }
            }
        }
    }

现在AcctBRef和AcctARef无法实现共同的接口,因为它们不是我的对象。或者如果它们不是我的对象,我仍然可以装饰它们成为我的对象吗?

6
你对“发送整个对象”的评论是什么意思?类实例是按值引用传递的,这意味着无论对象有多大,从方法到方法传递的数据都非常少(即一个指针)。 - mellamokb
ObjB.Exceptions жҳҜдёҖдёӘйқҷжҖҒи°ғз”Ёеҗ—пјҹ - Davin Tryon
另外,“Input”是ObjA和ObjB的内部类吗? - hometoast
ObjA.Exceptions只是一个例子,因为我不能放置真实的代码,这对您来说没有意义。 - akjha627
输入是一个内部类,但它们都来自不同的命名空间并具有完全相同的属性。我无法更改它们或拥有一个共同的接口,因为它们来自于一个超出我的控制的服务响应。 - akjha627
3个回答

2

如果ObjA和ObjB继承自相同的基类或接口,则在这种情况下甚至不需要使用泛型。

如果您有

interface IBaseClass 
{
   IEnumerable<Something> Exceptions {get;set;}
   InputType Input {get;set;}
}
class A : IBaseClass {}
class B : IBaseClass {}

您可以使用以下内容作为LogExceptions签名:

您只需使用此内容即可:

void LogExceptions(IBaseClass obj, int CustomerId) 
{
   Log(obj.Exceptions);
   Log(obj.Input);
}

如果它们没有从一个共同的接口继承,那么我建议它们应该这样做。

我知道这个技巧...但是ObjA和ObjB不受我的控制,尽管它们具有完全相似的属性...它们来自第三方服务,因此是不同的。 - akjha627
如果没有反射,你就必须为每个ObjA/ObjB添加一个覆盖。在这种情况下,为每种类型添加一个覆盖似乎更加清晰。 - hometoast

0

我认为,如果有4种方法,它们没有相同的方法签名,那完全没问题,它不一定总是要通用的,也必须易读。

如果你只需要Log(调用该方法时你知道的其中一种类型),为什么要进行4次调用Log(T1),Log(T2),Log(T3),Log(T4)呢?

话虽如此,你总是可以使用反射来玩耍,就像在你的情况下一样。


0

您不能将 Type 参数传递给 Log 方法。您必须传递 Type 参数的实例。

请尝试以下操作:

 private void LogExceptions<T1, T2>(T1 input, T2 exceptions, int customerId) 
    {
        Log(input);
        Log(exceptions);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接