【发布时间】:2011-05-11 18:53:18
【问题描述】:
我正在为另一个软件编写一个与 API 交互的工具。我的工具的一部分需要生成关于通过 API 找到的各种对象的报告,我希望这些报告包含标识每个对象的简单字符串。默认情况下,我计划使用 ToString() 为每个对象生成字符串。但是,毫不奇怪,我发现此 API 中的默认 ToString() 实现不是描述性的。
最初我想用一个长的 Switch 语句来做类似下面的代码的事情。尽管这很可能会变得难以控制。
public string GetAPIObjectDescrition(object obj)
{
Type t = obj.GetType();
Switch(t)
{
Case typeof(SomeAPIType):
SomeAPIType x = (SomeAPIType)obj;
return x.SomeProperty;
Case typeof(SomeOtherAPIType):
SomeOtherAPITypex = (SomeOtherAPIType)obj;
return x.SomeOtherProperty;
default:
return x.ToString();
}
}
接下来我尝试使用扩展方法(参见下面的代码)。 CustomObjectDescription() 按预期工作,但是当我尝试调用 ToString() 时,它只返回默认的 ToString() 结果。我以前从未使用过扩展方法,所以我可能会完全不以为然地认为这样的事情是可能的。
我不能保证 API 中遇到的每个类型都会有一个 CustomObjectDescription() 扩展,所以如果我采用这条路线,我最终将不得不每次都使用反射来检查当前对象是否具有 GetObjectDescription () 延期。如果可能的话,我想避免使用反射。
public static class APIObjectDescriptionExtensions
{
public static string ToString(this APIObject element)
{
return "ElementName = " + element.Name + " ElementID =" + element.Id.IntegerValue.ToString();
}
public static string CustomObjectDescription(this APIObject element)
{
return "ElementName = " + element.Name + " ElementID =" + element.Id.IntegerValue.ToString();
}
}
是否有人对我应该如何解决这个问题有任何其他建议?我更喜欢一种解决方案,其中每个 API 类型的代码相互独立(没有巨大的 Switch 语句)。
如果可能的话,我希望将一种类型的描述字符串代码继承到子类型,除非这些类型有自己唯一的描述字符串代码。
我认为可能有更好的解决方案,包括创建自定义 TypeConverters 或覆盖/扩展 System.Convert.ToString()?
更新
我认为下面的示例可能有助于阐明我想要做什么。最终,我希望能够从此 API 中获取任意类,直到运行时才知道其类型,并生成描述字符串。如果 Type 有我的自定义扩展方法,那么应该使用它,否则代码应该使用普通的旧 ToString()。
public static string GetDataDescription(object o)
{
//get the type of the input object
Type objectType = o.GetType();
//check to see if a description extension method is defined
System.Reflection.MethodInfo extensionMethod = objectType.GetMethod("MyDescriptionExtensionMethod");
if (extensionMethod != null)
{
//if a description extension method was found returt the result
return (string)extensionMethod.Invoke(o, new object[] { });
}
else
{
//otherwise just use ToString();
return o.ToString();
}
}
上面的代码不起作用,因为扩展方法aren't found by GetMethod()。
【问题讨论】:
-
您不能使用扩展方法隐藏实例方法,因为当编译器尝试绑定方法调用表达式时,首先会检查实例方法;有关详细信息,请参阅规范 (§7.6.5.1)。
-
实例方法将始终在任何具有相同名称的扩展方法之前使用(其他都相同)。因此,无法以这种方式使用 ToString。
标签: c# .net extension-methods tostring typeconverter