我有一个通用方法的接口:
interface IConverter
{
void Convert<T>(T value);
}
我想为任何类型实现它,但我也知道,对于string
,方法逻辑可以简化,所以我想专门为string
重载它(就像在{ {3}}):
class Converter : IConverter
{
public void Convert<T>(T value)
{
Console.WriteLine("Generic Method " + value);
}
public void Convert(string value)
{
Console.WriteLine("String Method " + value);
}
}
当我有Converter
的实例并直接调用方法时,它工作正常。代码
var converter = new Converter();
converter.Convert("ABC");
converter.Convert(123);
输出
String Method ABC
Generic Method 123
然而,当我使用界面时(就像在带有DI的任何应用程序中),我无法调用string
的重载。代码
var converter = (IConverter)new Converter();
converter.Convert("ABC");
converter.Convert(123);
输出:
Generic Method ABC
Generic Method 123
无论如何要完成调用string
重载方法而不进行类型检查,如
if (typeof(T) == typeof(string))
...
答案 0 :(得分:3)
没有。您将converter
投射到IConverter
,因此converter
变量只显示一种方法:Convert<T>(T value)
。
您可以通过在界面中添加Convert(string)
来解决此问题,或者根本不投放到界面并继续使用您的Converter
课程。只有这样才能看到其他方法。
答案 1 :(得分:1)
有两种方法,
您可以在界面中包含该方法,例如
interface IConverter
{
void Convert<T>(T value);
void Convert(string value);
}
将特定于string
的方法设为扩展方法
public static void Convert(this string str, string value)
{
// code here
}
答案 2 :(得分:1)
也许你的设计是倒置的,你的界面应该是通用的:
interface IConverter<T>
{
void Convert(T value);
}
这将允许您以特定方式实现特定类型:
class BaseConverter<T> : IConverter<T>
{
public void Convert(T value)
{ /* some common way */ }
}
class StringConverter : IConverter<string>
{
public void Convert(string value)
{ /* strings get converted here */ }
}
你可能会有一个&#34;工厂&#34;将提供正确的转换器实例的类:
class ConverterFactory
{
// this is basically "poor man's" service locator,
// but the same idea works with DI, where you
// would register individual comparers
public IConverter<T> Create<T>()
{
// use a Dictionary, or add that
// typeof(T) == typeof(string) check here
}
}
这类似于例如在.NET BCL中定义IComparer<T>
并与Comparer<T>.Default
结合的方式。
这也是可以更好地使用DI的方法,因为您的IConverter<T>
取决于T
,而拥有单个非泛型IConverter
无法告诉DI注入哪个特定实例
答案 3 :(得分:0)
你可以在你的泛型方法中进行一些类型检查。
public void Convert<T>(T value)
{
Console.WriteLine(typeof(T) == typeof(string) ? "String Method" : "Generic Method " + value);
}
但这样做会省略所有泛型的内容,不是吗?说不推荐这个。
无论如何只是因为两个方法具有相同的名称并不意味着它们 相等,因为编译器Convert(string)
和Convert<T>(T)
完全相同不同的方法。然而,接口只知道通用接口,因此当转换为接口时,根本不知道字符串方法。
正如Patrick已经提到的那样,在界面上省略了强制转换或实现了string-method。另一个 - 也是肮脏的黑客 - 将通用调用重定向到字符串方法:
class Converter : IConverter
{
public void Convert<T>(T value)
{
if (typeof(T) == typeof(string) this.Convert((string) value);
else Console.WriteLine("Generic Method " + value);
}
public void Convert(string value)
{
Console.WriteLine("String Method " + value);
}
}
答案 4 :(得分:0)
如果你真的想要保持界面相同,你可以使用类型检查:
class Converter : IConverter
{
public void Convert<T>(T value)
{
if (value is string)
{
Console.WriteLine("String Method " + (string)value);
}
else
{
Console.WriteLine("Generic Method " + value);
}
}
}
或者,正如其他人所说,您可以将Convert(string)添加到IConverter。