C# 返回泛型驱动类型的对象的泛型方法
我在C#中与泛型作斗争。考虑这段代码:C# 返回泛型驱动类型的对象的泛型方法,c#,generics,C#,Generics,我在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 SecondIm
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 {};
公共接口A{};
公共接口B:A{};
公共接口C:A{};
公共接口IMyInterface,其中T:A{};
公共类FirstImpl:IMyInterface,其中T:B{};
公共类SecondImpl:IMyInterface,其中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>();
}
}
public IMyInterface Create(),其中T:A
{
如果(T的类型为B){
返回新的FirstImpl();
}
如果(T的类型为C){
返回新的SecondImpl();
}
}
这在两个层面上都不起作用。第一种是返回类型。第二个问题是,我不能将“t”传递到第一个或第二个实现中,因为它们需要更具体的类型。你知道怎么解决这个问题吗 最短的方法是使用
Create()
方法添加额外的约束,如public IMyInterface Create(),其中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>;
}
public IMyInterface Create(),其中T:A,B,C
{
如果(T的类型为B)
{
返回新的FirstImpl();
}
如果(T的类型为C)
{
返回新的SecondImpl();
}
返回新的DefaultImpl;
}
最短的方法是使用Create()
方法添加额外的约束,如public IMyInterface Create(),其中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>;
}
public IMyInterface Create(),其中T:A,B,C
{
如果(T的类型为B)
{
返回新的FirstImpl();
}
如果(T的类型为C)
{
返回新的SecondImpl();
}
返回新的DefaultImpl;
}
如果您不介意反射,可以这样做:
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);
}
publicstaticimyinterface Create(),其中T:A
{
if(typeof(B).可从(typeof(T))中识别)
{
变量类型=类型(第一个impl);
var boundType=type.MakeGenericType(typeof(T));
return(IMyInterface)Activator.CreateInstance(boundType);
}
else if(typeof(C).IsAssignableFrom(typeof(T)))
{
变量类型=类型化(第二个impl);
var boundType=type.MakeGenericType(typeof(T));
return(IMyInterface)Activator.CreateInstance(boundType);
}
抛出新ArgumentException(“未知类型”+typeof(T).Name);
}
您可以在一个中尝试,如果您不介意反射,您可以这样做:
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);
}
publicstaticimyinterface Create(),其中T:A
{
if(typeof(B).可从(typeof(T))中识别)
{
变量类型=类型(第一个impl);
var boundType=type.MakeGenericType(typeof(T));
return(IMyInterface)Activator.CreateInstance(boundType);
}
else if(typeof(C).IsAssignableFrom(typeof(T)))
{
变量类型=类型化(第二个impl);
var boundType=type.MakeGenericType(typeof(T));
return(IMyInterface)Activator.CreateInstance(boundType);
}
抛出新ArgumentException(“未知类型”+typeof(T).Name);
}
只要有使用泛型类型或方法的代码,并且该代码对泛型类型参数进行了某种类型的测试,您就可以在一个中尝试。(毫无疑问,陷入反射会更糟。)泛型类型的关键在于编写不依赖于泛型类型的代码 在您的示例中,更好的方法如下:
static IMyInterface<T> CreateB<T>() where T : B
{
return new FirstImpl<T>();
}
static IMyInterface<T> CreateC<T>() where T : C
{
return new SecondImpl<T>();
}
static IMyInterface CreateB(),其中T:B
{
返回新的FirstImpl();
}
静态IMyInterface CreateC(),其中T:C
{
返回新的SecondImpl();
}
也就是说,编写不同的方法来处理每个场景。如果基于约束的方法能够奏效,调用方无论如何都必须知道它正在处理什么。因此,只要有不同的方法名就可以了,每个方法名都可以在相应的情况下使用
如果上述内容没有针对您的特定场景,请改进问题,使其包括一个良好的示例,不仅显示您尝试使用的泛型类型,还显示它们将在其中使用的上下文。任何时候您有使用泛型类型或方法的代码,这段代码对泛型类型参数进行了某种测试,但您做得不对。(毫无疑问,陷入反射会更糟。)泛型类型的关键在于编写不依赖于泛型类型的代码 在您的示例中,更好的方法如下:
static IMyInterface<T> CreateB<T>() where T : B
{
return new FirstImpl<T>();
}
static IMyInterface<T> CreateC<T>() where T : C
{
return new SecondImpl<T>();
}
static IMyInterface CreateB(),其中T:B
{
返回新的FirstImpl();
}
静态IMyInterface CreateC(),其中T:C
{
返回新的SecondImpl();
}
也就是说,编写不同的方法来处理每个场景。如果基于约束的方法能够奏效,调用方无论如何都必须知道它正在处理什么。因此,只要有不同的方法名就可以了,每个方法名都可以在相应的情况下使用
如果上述内容没有针对您的特定场景,请改进问题,使其包含一个好的内容,不仅显示您尝试使用的泛型类型,还显示它们将在其中使用的上下文。,问题是,从技术上讲,在调用
new FirstImpl()时,您无法让编译器相信泛型类型t实际上是B或B的派生类型代码>。有趣。值得深思。让我看看。你遗漏了几个新的关键字了吗?要理解这个问题已经够难了,不必处理那些即使满足您的要求也无法编译的代码。您是否打算编写返回新的FirstImpl()
和返回新的SecondImpl()代码>?嗯,问题出在哪里