-Dr_X- Ответов: 2

Фабрика универсального типа


Я не могу вызвать функцию Create<> Из-за ошибок компиляции.
Есть идеи?
enum ReportTypes
{
    Report1,
    Report2,
    Report3 
}

abstract class Report
{
    protected abstract bool Run();
}

class Report1 : Report
{
    protected override bool Run()
    { return true; }
}

class Report2 : Report
{
    protected override bool Run()
    { return true; }
}

class Report3 : Report
{
    protected override bool Run()
    { return true; }
}
class ReportFactory
{
    private static Dictionary<ReportTypes, Type> Reports = new Dictionary<ReportTypes, Type>()
    {
      {ReportTypes.Report1, typeof(Report1) },
      {ReportTypes.Report2, typeof(Report2)},
      {ReportTypes.Report3, typeof(Report3)},
    };

    static Report Create<T>() where T : Report, new()
    {
        return new T();
    }

    public static Report GetReport(ReportTypes reportType)
    {
        //Unable to get this line to work
        return ReportFactory.Create<Reports[reportType]>();
    }

}


Что я уже пробовал:

return ReportFactory.Create<typeof(Reports[reportType])>();
и
return ReportFactory.Create<Reports[reportType].GetType()>();

Я знаю, что могу просто сделать это, но вместо этого хотел использовать статическую функцию Create.
Report = (Report)ClassFactory.Create(Reports[reportType].GetType());

2 Ответов

Рейтинг:
2

F-ES Sitecore

Вы можете сделать это с помощью отражения

public static Report GetReport(ReportTypes reportType)
{
    Type t = Reports[reportType];

    MethodInfo method = typeof(ReportFactory)
        .GetMethods(BindingFlags.Static | BindingFlags.NonPublic)
        .First(m => m.Name == "Create");

    MethodInfo genericMethod = method.MakeGenericMethod(t);
    return (Report)genericMethod.Invoke(null, null);
            
}


Thomas Daniels

+5

Рейтинг:
12

Thomas Daniels

То, как вы используете дженерики, не поддерживается в C#. Между < и > ожидается имя типа, а не a Type объект,который не известен во время компиляции.

Чтобы создать что-то на основе объекта типа, вы можете использовать Активатор.Метод createinstance[^].