Как создать экземпляр wpf UserControl во время выполнения? [Дубликат]

569
задан Serj-Tm 23 May 2015 в 05:36
поделиться

8 ответов

Класс Activator в корневом пространстве имен System довольно мощный.

Существует много перегрузок для передачи параметров конструктору и тому подобное. Посмотрите документацию по адресу:

http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

или (новый путь)

https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance

Вот несколько простых примеров:

ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
728
ответ дан Jay 26 August 2018 в 05:00
поделиться

Если вы хотите использовать конструктор по умолчанию, то решение с использованием System.Activator, представленное ранее, возможно, наиболее удобно. Однако, если в типе отсутствует конструктор по умолчанию или вам нужно использовать нестандартный, тогда опция должна использовать отражение или System.ComponentModel.TypeDescriptor. В случае отражения достаточно знать только имя типа (с его пространством имен).

Пример с использованием отражения:

ObjectType instance = 
    (ObjectType)System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(
        typeName: objectType.FulName, // string including namespace of the type
        ignoreCase: false,
        bindingAttr: BindingFlags.Default,
        binder: null,  // use default binder
        args: new object[] { args, to, constructor },
        culture: null, // use CultureInfo from current thread
        activationAttributes: null
    );

Пример с помощью TypeDescriptor:

ObjectType instance = 
    (ObjectType)System.ComponentModel.TypeDescriptor.CreateInstance(
        provider: null, // use standard type description provider, which uses reflection
        objectType: objectType,
        argTypes: new Type[] { types, of, args },
        args: new object[] { args, to, constructor }
    );
7
ответ дан BSharp 26 August 2018 в 05:00
поделиться

Я могу решить этот вопрос, потому что я пытался реализовать простой метод CloneObject для произвольного класса (с конструктором по умолчанию)

С помощью общего метода вы можете потребовать, чтобы тип реализовал New ().

Public Function CloneObject(Of T As New)(ByVal src As T) As T
    Dim result As T = Nothing
    Dim cloneable = TryCast(src, ICloneable)
    If cloneable IsNot Nothing Then
        result = cloneable.Clone()
    Else
        result = New T
        CopySimpleProperties(src, result, Nothing, "clone")
    End If
    Return result
End Function

С не-generic предположим, что тип имеет конструктор по умолчанию и исключает исключение, если это не так.

Public Function CloneObject(ByVal src As Object) As Object
    Dim result As Object = Nothing
    Dim cloneable As ICloneable
    Try
        cloneable = TryCast(src, ICloneable)
        If cloneable IsNot Nothing Then
            result = cloneable.Clone()
        Else
            result = Activator.CreateInstance(src.GetType())
            CopySimpleProperties(src, result, Nothing, "clone")
        End If
    Catch ex As Exception
        Trace.WriteLine("!!! CloneObject(): " & ex.Message)
    End Try
    Return result
End Function
3
ответ дан Darrel Lee 26 August 2018 в 05:00
поделиться

Не работает ли общий T t = new T();?

9
ответ дан H. Pauwelyn 26 August 2018 в 05:00
поделиться

Если это для чего-то, что будет много называться в экземпляре приложения, намного быстрее выполнить компиляцию и кеширование динамического кода вместо использования активатора или ConstructorInfo.Invoke(). Две простые опции для динамической компиляции компилируются Linq Expressions или некоторые простые IL опкоды и DynamicMethod . В любом случае разница будет огромной, когда вы начнете получать плотные петли или несколько вызовов.

82
ответ дан Ian Kemp 26 August 2018 в 05:00
поделиться

Это довольно просто. Предположим, что ваше имя класса Car, а пространство имен - Vehicles, затем передайте параметр как Vehicles.Car, который возвращает объект типа Car. Подобным образом вы можете создать любой экземпляр любого класса динамически.

public object GetInstance(string strNamesapace)
{         
     Type t = Type.GetType(strNamesapace); 
     return  Activator.CreateInstance(t);         
}

Если ваше Полноценное имя (т. Е. Vehicles.Car в этом случае) находится в другой сборке, Type.GetType будет null. В таких случаях вы прокручиваете все сборки и находите Type. Для этого вы можете использовать приведенный ниже код

public object GetInstance(string strFullyQualifiedName)
{
     Type type = Type.GetType(strFullyQualifiedName);
     if (type != null)
         return Activator.CreateInstance(type);
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
     {
         type = asm.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
     }
     return null;
 }

. Вы можете получить экземпляр, вызвав вышеуказанный метод.

object objClassInstance = GetInstance("Vehicles.Car");
12
ответ дан Sarath Avanavu 26 August 2018 в 05:00
поделиться
public AbstractType New
{
    get
    {
        return (AbstractType) Activator.CreateInstance(GetType());
    }
}
114
ответ дан slavoo 26 August 2018 в 05:00
поделиться

Учитывая эту проблему, активатор будет работать, когда есть без параметров ctor. Если это ограничение, рассмотрим использование

System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject()
5
ответ дан Thulani Chivandikwa 26 August 2018 в 05:00
поделиться
Другие вопросы по тегам:

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