我有以下方法带有重载:
public string GetName(object obj)
{
return obj.ToString();
}
public string GetName(CustomClass cc)
{
return cc.Name + " - " + cc.Description;
}
现在,如果我使用拥有CustomClass的无类型IEnumerable调用该方法,则将调用GetName(object obj)来解决此问题,我已经修改了如下方法:
public string GetName(object obj)
{
if (obj is CustomClass)
return GetName(obj as CustomClass);
return obj.ToString();
}
我认为编写20条IF语句并捕获所有其他可能性非常烦人,是否有一种更简单的方法可以使用无类型的IEnumerable枚举来调用正确的重载?
这是调用GetName(object obj)的代码:
IEnumerable rawData = GetData(); //DataBase method that fetches a CustomClass
foreach (var rawDataItem in rawData)
{
Debug.Print(GetName(rawDataItem)); //calls the GetName(object obj) overload
}
请不要告诉我从CustomClass覆盖ToString,帮助我解决此方法调用问题。
好吧,您可以使用动态类型。这基本上会将重载解析推迟到执行时间:
foreach (dynamic rawDataItem in rawData)
{
Debug.Print(GetName(rawDataItem));
}
请注意,这里可能存在性能成本-可能很小且无关紧要,但是值得注意。
编辑:要处理事情的递归方面,您可能需要两个不同的名称,例如GetName
,GetNameImpl
在其中调用所有有用的重载的GetName
委托GetNameImpl
。因此,您将拥有:
// Note that dynamic as a parameter type is equivalent to object for callers.
// The dynamic part is only relevant within the method.
public string GetName(dynamic obj)
{
return GetNameImpl(obj);
}
// Fallback when no other overloads match
private string GetNameImpl(object obj)
{
...
}
private string GetNameImpl(IEnumerable obj)
{
// Maybe build up the name by calling GetName on each element?
}
请注意,这有一个潜在的问题:如果您对不同的接口有两个重载,并且一个类型同时实现了两个接口(但是该类型本身没有特定的重载),那么在执行时会出现异常。
如果希望调用者能够直接调用重载,则可以仅将动态的一个重命名为GetNameDynamic
,将其他的重命名GetName
为(并使其公开)。
我很少发现,dynamic
是一个很好的解决方案,但它会避免代码重复。我会尝试退后一步,说实话,找到一种不同的设计。您在问题中明确拒绝了它,但是多态是处理此问题的首选方式。您不必重写ToString
-您可以使所有自定义类型实现一个特定的接口,并在可用的情况下使用该接口。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句