0

我有一个界面

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
   }
}
4

4 回答 4

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实例的方法中执行if some 条件,不如在调用者中执行并再次利用泛型约束来避免反射及其性能损失。

归根结底,这是使用抽象工厂模式

// 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>();
}
于 2013-02-12T08:39:48.393 回答
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;
        }
    }
于 2013-02-12T08:39:15.263 回答
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();
        }
    }
}
于 2013-02-12T08:40:24.977 回答
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);

因此,如您所见,在这种情况下,泛型不是强制性的。但是,如果您确实有无参数构造函数,并且类型在编译时是已知的,那么您确实可以使用泛型为CreateTask方法提供类型参数,如下所示:

public static T CreateTask<T>() where T : ITask, new()
{
   return new T();
}

可以这样使用:

ITask myTast = TaskFactory.CreateTask<TaksA>();

两种实现都可以并存,并且在某些情况下两者都很有用。

于 2013-02-12T08:43:05.153 回答