Вопрос по types, generics, c# – Общий класс из параметра типа

4

Есть ли способ создать универсальный класс из параметра типа.

У меня есть что-то вроде этого:

public class SomeClass
{
    public Type TypeOfAnotherClass { get; set; }
}

public class OneMoreClass
{
}

public class GenericClass<T>
    where T : class
{
    public void DoNothing() {}
}

public class GenericClass
{
    public static GenericClass<T> GetInstance<T>(T ignored)
        where T : class
    {
        return new GenericClass<T>();
    }
}

Я хочу создать GenericClass из типа. Пример:

var SC = new SomeClass();
SC.TypeOfAnotherClass = typeof(OneMoreClass);
var generic = GenericClass.GetInstance(SC.TypeOfAnotherClass);

Assert.AreEqual(typeof(GenericClass<OneMoreClass>), generic.GetType());

Здесь я ожидаю получить экземплярGenericClass<OneMoreClass> но я получаюGenericClass<Type>

Я также попытался использовать экземпляр этого типа. Пример:

var generic = GenericClass.GetInstance(Activator.CreateInstance(SC.TypeOfAnotherClass));

На этот раз я получаюGenericClass<object>

Есть ли способ выполнить эту задачу?

Ваш Ответ

2   ответа
1

что именно вы спрашиваете здесь. Если я вас правильно понял, это то, что вы ищете:

public class GenericClass
{
    public static GenericClass<T> GetInstance<T>(T ignored)
        where T : class
    {
        return new GenericClass<T>();
    }

    public static GenericClass<T> GetInstance<T>()
        where T : class
    {
        return new GenericClass<T>();
    }
}

Че использование:

  var generic1 = GenericClass.GetInstance<OneMoreClass>();
  var generic2 = GenericClass.GetInstance(new OneMoreClass());

Утверждения:

Assert.AreEqual(typeof(GenericClass<OneMoreClass>), generic1.GetType());
Assert.AreEqual(typeof(GenericClass<OneMoreClass>), generic2.GetType());
9

OneMoreClass) во время сборки, тогда вы должны просто использовать его:

var generic = GenericClass.GetInstance<OneMoreClass>();

Но я предполагаю, что вы не знаете об этом во время сборки и должны получитьtype во время выполнения. Вы можете сделать это с помощью отражения, но это не красиво и медленно:

public class GenericClass
{
    public static object GetInstance(Type type)
    {
        var genericType = typeof(GenericClass<>).MakeGenericType(type);
        return Activator.CreateInstance(genericType);
    }
}

Поскольку вы не знаете результирующий тип во время сборки, вы не можете вернуть ничего, кромеobject (или жеdynamic) из метода.

Вот насколько медленнее (на 100 000 создает)

public class GenericClass
{
    public static object GetInstance(Type type)
    {
        var genericType = typeof(GenericClass<>).MakeGenericType(type);
        return Activator.CreateInstance(genericType);
    }

    public static GenericClass<T> GetInstance<T>()
        where T : class
    {
        return new GenericClass<T>();
    }
}

    [Test]
    public void CanMakeGenericViaReflection_ButItsSlow()
    {
        var timer = new Stopwatch();
        var SC = new SomeClass();
        SC.TypeOfAnotherClass = typeof(OneMoreClass);

        timer.Start();
        for (int x = 0; x < 100000; x++)
        {
            GenericClass.GetInstance(SC.TypeOfAnotherClass);
        }
        timer.Stop();
        Console.WriteLine("With Reflection: " + timer.ElapsedMilliseconds + "ms.");

        timer.Restart();
        for (int x = 0; x < 100000; x++)
        {
            GenericClass.GetInstance<OneMoreClass>();
        }
        timer.Stop();
        Console.WriteLine("Without Reflection: " + timer.ElapsedMilliseconds + "ms.");
    }

Результаты:

With Reflection: 243ms.
Without Reflection: 2ms.

Так что чуть более чем в 100 раз медленнее.

В отношении дженериков следует отметить, что<T>s в дженериках разрешаются вbuild-time компилятором C #, и реальные имена классов вставляются. Когда вам придется отложить это до времени выполнения, вы в конечном итоге платите цену производительности.

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededobjectError: User Rate Limit ExceededinterfaceError: User Rate Limit ExceededGenericClassError: User Rate Limit Exceeded Merdan Gochmuradov
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы