【问题标题】:Passing a varying type to a generic method将可变类型传递给泛型方法
【发布时间】:2014-07-01 18:41:03
【问题描述】:

我确定这一定是可能的,但目前我无法做到。

我有一个基于石英引擎的初始化多个作业的方法。例如

private void InitialiseJobs(IScheduler scheduler)
{
    var ns = "Proto.QuartzScheduler.Domain.Jobs";
    var classname = "ExampleJob";

    var jobSetup = new JobSetup<type>(scheduler);
    jobSetup.Run(10);

    var second_jobSetup = new JobSetup<ExampleJob>(scheduler);
    second_jobSetup.Run(20);
}

这项工作的最后两行。我希望能够通过命名空间和类名定义类型并传入泛型类型。例如,用我定义的任何内容替换 ExampleJob

任何帮助表示赞赏。

很抱歉,除了阻止以下建议发挥作用外,我应该给你们更多的东西:

public class JobSetup<TType> where TType : IJobToDo
{

    private readonly IScheduler scheduler;
    private readonly IJobDetail jobDetail;
    private readonly JobKey jobKey;

    public JobSetup(IScheduler scheduler)
    {
        this.scheduler = scheduler;
        this.jobKey = new JobKey(Guid.NewGuid().ToString(), typeof(TType).ToString());
        this.jobDetail = JobBuilder
                            .Create<JobRunner<TType>>()
                            .WithIdentity(this.jobKey)
                            .Build();
    }

    public void Set<TPropertyType>(Expression<Func<TType, TPropertyType>> expression, TPropertyType value)
    {

        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new ArgumentException("Could not convert the expression to a member expression.");
        }

        this.jobDetail.JobDataMap[memberExpression.Member.Name] = value;
    }

    public TPropertyType Get<TPropertyType>(Expression<Func<TType, TPropertyType>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new ArgumentException("Could not convert the expression to a member expression.");
        }

        return (TPropertyType)this.jobDetail.JobDataMap.Get(memberExpression.Member.Name);
    }

    public void Run(int number_of_seconds)
    {

        var trigger = new SimpleTriggerImpl
        (
            this.jobKey.Name,
            this.jobKey.Group,
            DateTime.UtcNow,
            null,
            SimpleTriggerImpl.RepeatIndefinitely,
            TimeSpan.FromSeconds(number_of_seconds)
        );

        this.scheduler.ScheduleJob(this.jobDetail, trigger);
    }
}

还有界面:

public interface IJobToDo
{
    void Run();
}

还有ExampleJob

public class ExampleJob : IJobToDo
{

    public void Run()
    {
        Console.WriteLine("HelloJob is executing. {0}", System.DateTime.Now.ToUniversalTime());

    }
}

我没有正在激活的类的无参数构造函数?

请继续提出建议

干杯

【问题讨论】:

  • 请解释您遇到了什么错误。以及为什么上面链接的问题还不够。
  • 我没有被激活的类的无参数构造函数?
  • 我不知道,是吗?
  • 不,我不知道! - 实施上述我没有机会调用 second_jobSetup.Run(20);只是 second_jobSetup.Run();第一个在 JobSetup 类中,第二个在 ExampleJob 类中。我需要第一个。

标签: c# generics types


【解决方案1】:

如果您的 JobSetup&lt;&gt; 泛型类实现了一些接口,例如:

interface IJobSetup
{
    void Run(int x);
}

可以通过接口使用Activator创建的对象,更加优雅。所以写成:

private void InitialiseJobs(IScheduler scheduler)
{
    var classname = "Proto.QuartzScheduler.Domain.Jobs.ExampleJob";
    Type genericTypeParameter = Type.GetType(classname);
    Type genericClass = typeof(JobSetup<>);
    Type constructedClass = genericClass.MakeGenericType(genericTypeParameter);

    var setup = Activator.CreateInstance(constructedClass) as IJobSetup;
    setup.Run(20);
}

【讨论】:

  • 嗯.. 为什么投反对票?我已经回答了特定于案例的场景,添加了有关接口的信息(指出如何使用 Activator 创建的对象)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 2016-02-12
相关资源
最近更新 更多