我有一种情况,我有一个需要几个重载的方法。我有一个相当常见的场景,如果某个条件为真,我会调用其中一个重载,否则我会调用其他重载。我决定聪明一点,把通用代码重构为一个泛型方法,该方法接受一个对象和一个条件,然后调用重载的方法或调用通用代码。
一个非常简单的代码示例:
/// <summary>
/// Dummy interface
/// </summary>
public interface ITest1
{ }
/// <summary>
/// Dummy interface
/// </summary>
public interface ITest2
{ }
/// <summary>
/// Generic Class
/// </summary>
public class GenericClass
{
/// <summary>
/// First overload
/// </summary>
/// <param name="test1"></param>
public void TestMethod(ITest1 test1)
{ }
/// <summary>
/// Second overload
/// </summary>
/// <param name="test2"></param>
public void TestMethod(ITest2 test2)
{ }
/// <summary>
/// method with common logic
/// </summary>
/// <typeparam name="TInterfaceType">
/// Type of the test object
/// </typeparam>
/// <param name="test">
/// Test object to pass to the method.
/// </param>
public void ConditionallyCallTest<TInterfaceType>(
TInterfaceType test, bool someLogic)
{
if (someLogic)
{
this.TestMethod(test);
}
else
{
// .. Perform Common operations here
}
}
}忽略这一事实,如果你编译这段代码,你会得到一个编译器错误,它不能将TInterfaceType转换成ITest1。
我希望编译器等到我指定要进行类型检查的类型,所以:
GenericClass g = new GenericClass();
// We have an overload, so this is OK:
g.ConditionallyCallTest<ITest1>(test1);
// We have an overload, so this is OK:
g.ConditionallyCallTest<ITest2>(test2);
// Compiler error, no overload available:
g.ConditionallyCallTest<UnknownType>(obj);有没有可能用C#来做这样的事情?
我还尝试使用where子句指定允许的类型,但我不知道如何让where子句指定指定类型之间的一个或多个关系,只指定一个AND关系。
编辑
当我使用mentioned in the comments below时,我试图避免创建匹配的重载方法,那么有没有其他建议来解决这个问题,或者我是否受到了这里的语言的限制?
发布于 2009-03-13 22:46:07
你甚至需要一个泛型方法吗?只需使用普通重载即可。
/// <summary>
/// Dummy interface
/// </summary>
public interface ITest1
{ }
/// <summary>
/// Dummy interface
/// </summary>
public interface ITest2
{ }
/// <summary>
/// Generic Class
/// </summary>
public class GenericClass
{
/// <summary>
/// First overload
/// </summary>
/// <param name="test1"></param>
public void TestMethod(ITest1 test1)
{ }
/// <summary>
/// Second overload
/// </summary>
/// <param name="test2"></param>
public void TestMethod(ITest2 test2)
{ }
public void ConditionallyCallTest(ITest1 test, bool someLogic)
{
if(Common(someLogic))
return;
TestMethod(test);
}
public void ConditionallyCallTest(ITest2 test, bool someLogic)
{
if(Common(someLogic))
return;
TestMethod(test);
}
private bool Common(bool someLogic)
{
if (someLogic)
{
return false;
}
// .. Perform Common operations here
return true;
}
}发布于 2009-03-13 22:57:44
为所有类型抽象出一个公共接口,并为此使用多态性。
发布于 2009-03-13 22:35:50
编译器必须能够在不知道要传递什么的情况下编译代码。在本例中,我所说的“你的代码”指的是包含方法的类。
换句话说,它必须知道对TestMethod的调用是合法的,这是基于它在编译执行调用的方法时所知道的情况。
在这种情况下,它对TInterfaceType一无所知,因此不能保证这是正常的,因此它会抱怨。
您可以告诉编译器TInterfaceType泛型类型必须实现一个或多个接口,但不能告诉它该类型必须实现一个或另一个接口。
换句话说,不,你不能在没有一些造型的情况下做到这一点。
要做到这一点,一种方法是创建多个重载,每个重载对应于您希望支持的每种接口类型。
泛型类型基本上是为了“任何可能的类型”,其中你有一个有限的类型集是允许的。
使用泛型时,如果不显式检查类型是实现一个接口还是另一个接口(即强制转换),就无法做到这一点,从而直接调用显式方法。
您也不能重载该方法,并通过泛型约束来区分它,因为方法签名不能仅通过泛型约束来区分。
https://stackoverflow.com/questions/644841
复制相似问题