我有一个界面
public interface ITask
{
void MethodA();
}
实现ITask的两个类
public class TaskA: ITask
{
public void MethodA();
}
和
public class TaskB : TaskA,ITask
{
}
现在基于某些条件,我希望创建TaskA或TaskB的实例。我如何在这里使用泛型以及如何初始化对象
public void MethodB(int a)
{
ITask task;
if(a=1)
{
// use TaskA
}
else
{
//use TaskB
}
}
答案 0 :(得分:1)
如果您的意思是可能有通用类型或方法参数,则可以这样做:
public class A<T> where T : ITask, new()
{
public void Some()
{
T instanceOfITask = new T();
}
}
...或:
public class A
{
public void Some<T>() where T : ITask, new()
{
T instanceOfITask = new T();
}
}
通用约束允许您指定T
必须实现ITask
并且必须具有公共无参数构造函数。
由于OP编辑了这个问题,我当前的答案可能已经过时了。
顺便说一下,由于我不知道您的实际要求,我可以说您仍然可以使用此解决方案。
而不是在应该处理 ITask 实例的方法中执行如果某些条件,您可以在调用者中再次利用通用约束来避免反射及其性能损失。
在一天结束时,这是使用抽象工厂模式:
// The abstract factory!
public static class TaskFactory
{
public static T Create<T>() where T : ITask, new()
{
T instanceOfITask = new T();
// more stuff like initializing default values for the newly-created specific task
return instanceOfITask;
}
}
稍后,某处:
ITask task = null;
// Depending on the condition, you invoke the factory method with different implementation of ITask
if([some condition])
{
task = TaskFactory.Create<MySpecificTaskImplementationA>();
}
else
{
task = TaskFactory.Create<MySpecificTaskImplementationB>();
}
答案 1 :(得分:0)
假设在你的Itask中我们有
public interface Itask
{
IQueryable<T> TaskA();
Iqueryable<T> TaskB();
}
然后创建实例..
public class Tasks:Itask
{
CategoryDataEntities db = new CategoryDataEntities();
public IQueryable<Category> CategoryList()
{
IQueryable<Category> categoryLiist = db.Categories.AsQueryable();
return categoryLiist;
}
}
答案 2 :(得分:0)
我怀疑是否需要仿制药。你已经有了一个接口合同,这很好。在这种情况下,您只需要一个工厂类或方法,它根据某些输入条件构建实例。
使用Activator.CreateInstance()假设ITask的实现者可以处于动态加载的程序集中。
class Factory
{
public ITask Build(string input)
{
switch(input) {
case "A":
return (ITask)Activator.CreateInstance(typeof(TaskA));
case "B":
return (ITask)Activator.CreateInstance(typeof(TaskB));
default;
throw new Exception();
}
}
}
答案 3 :(得分:0)
似乎你根本不需要仿制药,似乎你需要一个工厂。这是一个简单而天真的实现:
public static class TaskFactory
{
public static ITask CreateTask(TaskType taskType)
{
switch (taskType)
cast TaskType.TaskA:
return new TaskA();
cast TaskType.TaskB:
return new TaskB();
default:
throw new InvalidArgumentException("unknown task type");
}
}
其中TaskType
是枚举定义如下:
public enum TaskType
{
TaskA,
TaskB,
}
您可以在
等代码中使用此功能ITask myTast = TaskFactory.CreateTask(TaskType.TaskA);
因此,正如您所看到的,在这种情况下,泛型不是强制性的。但是,如果你确实有paremeterless构造函数,并且类型在编译时是已知的,那么你确实可以使用泛型为CreateTask
方法提供类型参数,如下所示:
public static T CreateTask<T>() where T : ITask, new()
{
return new T();
}
可以像:
一样使用ITask myTast = TaskFactory.CreateTask<TaksA>();
这两个实现都可以并存,并且有两种情况都是有用的。