我正在做一个小例子来检查参数的类型是否有效.
class A
{
}
class B
{
}
class C
{
}
class D
{
public void SomeMethod<T>(T t) where T : class
{
if (t is A)
{
A a = t as A;
}
else if (t is B)
{
B b = t as B;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我可以打电话:
A a = new A();
SomeMethod<A>(a);
B b = new B();
SomeMethod<B>(b);
Run Code Online (Sandbox Code Playgroud)
现在,我想阻止将类传递C给SomeMethod.我想要实现的目标:
C c = new C();
SomeMethod<C>(c); // error
Run Code Online (Sandbox Code Playgroud)
为此,我尝试过:
public void SomeMethod<T>(T t) where T : A
{
// accept only class A
}
Run Code Online (Sandbox Code Playgroud)
要么
public void SomeMethod<T>(T t) where T : B
{
// accept only class B
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何声明SomeMethod与T可A或B在同一时间?就像:
public void SomeMethod<T>(T t) where T : A, B
{
// accept class A and class B
}
Run Code Online (Sandbox Code Playgroud)
正如李提到的,这违背了仿制药的目的.为了说明你所描述的内容,只需为每种情况编写重载
class A { }
class B { }
class C { }
class D
{
public void SomeMethod(A a)
{
//Do stuff with a
}
public void SomeMethod(B b)
{
//Do stuff with b
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想要运行时错误,可以执行以下操作:
class A { }
class B { }
class C { }
class D
{
public void SomeMethod<T>(T t) where T : class
{
if (t is A)
{
A a = t as A;
}
else if (t is B)
{
B b = t as B;
}
else //if (t is C)
{
throw new ArgumentException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这是一个糟糕的解决方案.重载解决方案仍然更清晰,并且会产生编译时错误.