Динамически создать объект <Type>
У меня есть таблица в моей базе данных, которую я использую для управления отношениями в моем приложении. это довольно простой в ней характер - parentType, parentId, childType, childId... все как ints. Я сделал эту настройку раньше, но я сделал это с настройкой switch/case, когда у меня было 6 разных таблиц, которые я пытался связать. Теперь у меня есть 30 таблиц, с которыми я пытаюсь это сделать, и я хотел бы иметь возможность сделать это, не записывая 30 записей в моей команде switch.
Есть ли способ, с помощью которого я могу ссылаться на класс .Net? Я знаю, что это неверно (потому что я пробовал несколько вариантов этого):
Type t = Type.GetType("WebCore.Models.Page");
object page = new t();
Я знаю, как получить тип объекта, но как я могу использовать его "на лету" для создания нового объекта?
Ответы
Ответ 1
Эта ссылка должна помочь:
http://msdn.microsoft.com/en-us/library/system.activator.createinstance(VS.71).aspx
Activator.CreateInstance создаст экземпляр указанного типа.
вы можете обернуть это в общий метод следующим образом:
public T GetInstance<T>(string type)
{
return (T)Activator.CreateInstance(Type.GetType(type));
}
Ответ 2
Если тип известен вызывающему, существует лучший, более быстрый способ, чем использование Activator.CreateInstance: вместо этого вы можете использовать общее ограничение на метод, который указывает, что он имеет конструктор без параметров без параметров.
Выполнение этого способа безопасно и не требует отражения.
T CreateType<T>() where T : new()
{
return new T();
}
Ответ 3
Вы хотите использовать Activator.CreateInstance
.
Вот пример того, как он работает:
using System;
using System.Runtime.Remoting;
class Program
{
static void Main()
{
ObjectHandle o = Activator.CreateInstance("mscorlib.dll", "System.Int32");
Int32 i = (Int32)o.Unwrap();
}
}
Ответ 4
public static T GetInstance<T>(params object[] args)
{
return (T)Activator.CreateInstance(typeof(T), args);
}
Ответ 5
Вот функция, которую я написал, которая клонирует запись типа T, используя отражение.
Это очень простая реализация, я не обрабатывал сложные типы и т.д.
public static T Clone<T>(T original)
{
T newObject = (T)Activator.CreateInstance(original.GetType());
foreach (var prop in original.GetType().GetProperties())
{
prop.SetValue(newObject, prop.GetValue(original));
}
return newObject;
}
Я надеюсь, что это может помочь кому-то.
Ассаф
Ответ 6
Предполагая, что у вас есть следующий тип:
public class Counter<T>
{
public T Value { get; set; }
}
и у вас есть квалифицированное имя сборки типа, вы можете построить его следующим образом:
string typeName = typeof(Counter<>).AssemblyQualifiedName;
Type t = Type.GetType(typeName);
Counter<int> counter =
(Counter<int>)Activator.CreateInstance(
t.MakeGenericType(typeof(int)));
counter.Value++;
Console.WriteLine(counter.Value);