好吧,基本上 C# 不允许模板特化,除非通过这样的继承:
interface IFoo<T> { }
class Bar { }
class FooBar : IFoo<Bar> { }
至少它在编译时不支持这一点。但是,您可以使用 RTTI 来完成您想要实现的目标:
public bool Save<T>(T entity)
{
// Check if "entity" is of type "SpecificClass"
if (entity is SpecificClass)
{
// Entity can be safely casted to "SpecificClass"
return SaveSpecificClass((SpecificClass)entity);
}
// ... other cases ...
}
该is
表达式对于执行运行时类型检查非常方便。它的工作原理类似于以下代码:
if (entity.GetType() == typeof(SpecificClass))
// ...
编辑:未知类型使用以下模式很常见:
if (entity is Foo)
return DoSomethingWithFoo((Foo)entity);
else if (entity is Bar)
return DoSomethingWithBar((Bar)entity);
else
throw new NotSupportedException(
String.Format("\"{0}\" is not a supported type for this method.", entity.GetType()));
编辑2:正如其他答案建议重载该方法时,SpecializedClass
如果您使用多态性,您需要小心。如果您正在为存储库使用接口(这实际上是设计存储库模式的一种好方法),那么在某些情况下,重载会导致您调用错误的方法 get 的情况,无论您是否将对象传递SpecializedClass
给界面:
interface IRepository
{
bool Save<T>(T entity)
where T : class;
}
class FooRepository : IRepository
{
bool Save<T>(T entity)
{
}
bool Save(Foo entity)
{
}
}
如果您直接FooRepository.Save
使用以下实例调用,则此方法有效Foo
:
var repository = new FooRepository();
repository.Save(new Foo());
但是,如果您正在调用接口(例如,如果您正在使用模式来实现存储库创建),这将不起作用:
IRepository repository = GetRepository<FooRepository>();
repository.Save(new Foo()); // Attention! Call's FooRepository.Save<Foo>(Foo entity) instead of FooRepository.Save(Foo entity)!
使用 RTTI 只有一种Save
方法,你会没事的。