我在C#中苦苦寻找泛型。考虑一下这段代码:
public interface A {};
public interface B : A {};
public interface C : A {};
public interface IMyInterface<in T> where T : A {};
public class FirstImpl<T> : IMyInterface<T> where T : B {};
public class SecondImpl<T> : IMyInterface<T> where T : C {};
现在我需要一些工厂,它接受一个类型并返回正确的实现:
public IMyInterface<T> Create<T>() where T : A
{
if(typeof(T) is B) {
return new FirstImpl<T>();
}
if(typeof(T) is C) {
return new SecondImpl<T>();
}
}
这并不适用于两个层面。第一个是返回类型。第二个是我无法通过&#34; T&#34;进入第一个或第二个实现,因为它们需要更具体的类型。不知道怎么解决这个问题?
答案 0 :(得分:3)
每当你有使用泛型类型或方法的代码,并且该代码对泛型类型参数进行某种测试时,你做错了。 (恕我直言,不言而喻,反思更糟糕。)泛型类型的全部意义在于编写不依赖于泛型类型的代码。
在您的示例中,更好的方法是这样的:
static IMyInterface<T> CreateB<T>() where T : B
{
return new FirstImpl<T>();
}
static IMyInterface<T> CreateC<T>() where T : C
{
return new SecondImpl<T>();
}
即。编写不同的方法来处理每个场景。如果基于约束的方法能够起作用,呼叫者将不得不知道它已经处理了什么。因此,只有具有不同的方法名称并不是问题,每个方法名称都适用于相应的情况。
如果以上内容无法解决您的具体情况,请改进问题,使其包含一个好的Minimal, Complete, and Verifiable code example,不仅会显示您尝试使用的通用类型,还会显示它们的上下文使用
答案 1 :(得分:2)
如果你不介意反思,你可以这样做:
public static IMyInterface<T> Create<T>() where T : A
{
if (typeof(B).IsAssignableFrom(typeof(T)))
{
var type = typeof(FirstImpl<>);
var boundType = type.MakeGenericType(typeof(T));
return (IMyInterface<T>) Activator.CreateInstance(boundType);
}
else if(typeof(C).IsAssignableFrom(typeof(T)))
{
var type = typeof(SecondImpl<>);
var boundType = type.MakeGenericType(typeof(T));
return (IMyInterface<T>) Activator.CreateInstance(boundType);
}
throw new ArgumentException("unknown type " + typeof(T).Name);
}
您可以在.net fiddle
中试用答案 2 :(得分:1)
如果您想保持设计完整,最简单的方法是使用Create<T>()
方法添加额外约束,例如public IMyInterface<T> Create<T>() where T : A , B, C
。您可能需要一个默认情况的实现来使方法完成。
public IMyInterface<T> Create<T>() where T : A, B, C
{
if (typeof(T) is B)
{
return new FirstImpl<T>();
}
if (typeof(T) is C)
{
return new SecondImpl<T>();
}
return new DefaultImpl<T>;
}