标签: activator

如何使用反射动态创建通用C#对象?

在C#中我有以下对象:

public class Item
{ }

public class Task<T>
{ }

public class TaskA<T> : Task<T>
{ }

public class TaskB<T> : Task<T>
{ }
Run Code Online (Sandbox Code Playgroud)

我想使用C#reflection(Activator.CreateInstance)动态创建TaskA或TaskB .但是我不知道手头的类型,所以我需要动态创建基于字符串的TaskA,如"namespace.TaskA"或"namespace.TaskAB".

c# generics reflection activator

128
推荐指数
2
解决办法
16万
查看次数

C#使用Activator.CreateInstance

昨天我问了一个关于使用反射或策略模式动态调用方法的问题.

但是,从那时起,我决定将方法更改为实现公共接口的各个类.原因是,每个类虽然具有一些相似之处,但也执行该类所特有的某些方法.

我一直在使用这样的策略:

switch (method)
{
    case "Pivot":
        return new Pivot(originalData);
    case "GroupBy":
        return new GroupBy(originalData);
    case "Standard deviation":
        return new StandardDeviation(originalData);
    case "% phospho PRAS Protein":
        return new PhosphoPRASPercentage(originalData);
    case "AveragePPPperTreatment":
        return new AveragePPPperTreatment(originalData);
    case "AvgPPPNControl":
        return new AvgPPPNControl(originalData);
    case "PercentageInhibition":
        return new PercentageInhibition(originalData);
    default:
        throw new Exception("ERROR: Method " + method + " does not exist.");
}
Run Code Online (Sandbox Code Playgroud)

但是,随着潜在类数量的增加,我将需要不断添加新类,从而打破关闭修改规则.

相反,我使用了一个解决方案:

var test = Activator.CreateInstance(null, "MBDDXDataViews."+ _class);
       ICalculation instance = (ICalculation)test.Unwrap();
       return instance;
Run Code Online (Sandbox Code Playgroud)

实际上,_class参数是在运行时传入的类的名称.这是一种常见的方法,这会有任何性能问题吗?

我很反思,所以欢迎你提出建议.

c# reflection activator

50
推荐指数
4
解决办法
7万
查看次数

如何使用Activator创建泛型类型的实例并将其转换回该类型?

我有一个泛型类型Store<T>,用于Activator创建这种类型的实例.现在,在使用Activator之后,我可以将结果对象的类型转换object回实例化类型吗?我知道我用来实例化泛型的类型.请参阅以下代码:

class Store<T> where T : IStorable 
{}

class Beer : IStorable 
{}

class BeerStore : Store<Beer>
{}

Type storeType = someObjectThatImplementsIStorable.GetType();
Type classType = typeof(Store<>);
Type[] typeParams = new Type[] { storeType };   
Type constructedType = classType.MakeGenericType(typeParams);

object x = Activator.CreateInstance(constructedType, new object[] { someParameter });
Run Code Online (Sandbox Code Playgroud)

我想做的是这样的事情:

var store = (Store<typeof(objectThatImplementsIStorable)>)x;
Run Code Online (Sandbox Code Playgroud)

但由于显而易见的原因,这不起作用.作为替代方案,我试过:

var store = (Store<IStorable>)x;
Run Code Online (Sandbox Code Playgroud)

这可能在我看来有效,但给出了一个InvalidCastException.

如何再次访问Store<T>对象中我知道的方法x

c# generics reflection activator

36
推荐指数
2
解决办法
3万
查看次数

快速创建对象而不是Activator.CreateInstance(type)

我正在努力提高应用程序的性能.我们有很多Activator.CreateInstance调用引起了一些悲伤.

我们基于一个接口(ITabDocument)实例化了很多类,在浏览后我想到了使用这段代码:

代码并不比使用我们拥有的Activator.CreateInstance代码更好(实际上稍慢).

    public static Func<T> CreateInstance<T>(Type objType) where T : class, new()
    {
        var dynMethod = new DynamicMethod("DM$OBJ_FACTORY_" + objType.Name, objType, null, objType);
        ILGenerator ilGen = dynMethod.GetILGenerator();
        ilGen.Emit(OpCodes.Newobj, objType.GetConstructor(Type.EmptyTypes));
        ilGen.Emit(OpCodes.Ret);
        return (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>));
    }
Run Code Online (Sandbox Code Playgroud)

我想知道为什么会这样,我所做的只是:

ITabDocument document = CreateInstance<ITabDocument>(Type.GetType("[Company].Something"));
Run Code Online (Sandbox Code Playgroud)

是否有更好的方法来创建有助于上述内容的对象?当你不确定具体的类型时,它有点难.

c# reflection reflection.emit createinstance activator

31
推荐指数
4
解决办法
3万
查看次数

System.Activator.CreateInstance(T)的性能问题是否足以阻止我们随便使用它?

System.Activator.CreateInstance(T)方法是否有性能问题(因为我怀疑它使用反射)大到足以阻止我们随便使用它?

.net performance instantiation activator

30
推荐指数
4
解决办法
1万
查看次数

我如何使用Activator.CreateInstance与字符串?

在我的反射代码中,我遇到了我的通用代码部分的问题.特别是当我使用一个字符串.

var oVal = (object)"Test";
var oType = oVal.GetType();
var sz = Activator.CreateInstance(oType, oVal);
Run Code Online (Sandbox Code Playgroud)

例外

An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll

Additional information: Constructor on type 'System.String' not found.
Run Code Online (Sandbox Code Playgroud)

我试过这个用于测试目的,它也发生在这个单一的衬里

var sz = Activator.CreateInstance("".GetType(), "Test");
Run Code Online (Sandbox Code Playgroud)

我最初写的

var sz = Activator.CreateInstance("".GetType());
Run Code Online (Sandbox Code Playgroud)

但我得到这个错误

Additional information: No parameterless constructor defined for this object.
Run Code Online (Sandbox Code Playgroud)

如何使用反射创建字符串?

.net c# reflection activator

28
推荐指数
2
解决办法
3万
查看次数

.NET:无法将对象转换为它实现的接口

我有一个类(TabControlH60),它继承自基类(UserControl)并实现一个接口(IFrameworkClient).我使用.NET Activator类实例化对象.使用返回的实例,我可以转换为UserControl基类,但不能转换为接口.我得到的例外是在代码snipet下面.如何转换为界面?

object obj = Activator.CreateInstance(objType);
Type[] interfaces = obj.GetType().GetInterfaces(); // contains IFrameworkClient

m_Client = (UserControl)obj;                 // base class cast works
IFrameworkClient fc = (IFrameworkClient)obj; // interface cast fails

// Note: The (IFrameworkClient)obj cast works fine in the debugger Watch window.
{"Unable to cast object of type 'FPG.H60.AFF.TabControlH60' to type 
    'FPG.AFF.Interfaces.IFrameworkClient'."}
Run Code Online (Sandbox Code Playgroud)

c# casting interface base-class activator

24
推荐指数
4
解决办法
3万
查看次数

Activator.CreateInstance找不到构造函数(MissingMethodException)

我有一个具有以下构造函数的类

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;  
}
Run Code Online (Sandbox Code Playgroud)

以及没有参数的默认构造函数.

接下来我正在尝试创建一个实例,但它只能在没有参数的情况下工作:

var designer = Activator.CreateInstance(designerAttribute.Designer);
Run Code Online (Sandbox Code Playgroud)

这工作正常,但如果我想传递参数,它不会:

var designer = Activator.CreateInstance(designerAttribute.Designer, new DelayComposite(4));
Run Code Online (Sandbox Code Playgroud)

这导致MissingMethodException:

未找到构造函数类型Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesigner

这里有什么想法?


问题是我真的需要在施工期间传递一个物体.

你看我有一个设计器,它加载了从中继承的所有类型CompositeBase.然后将这些添加到列表中,用户可以从中将它们拖动到设计器.执行此操作后,将拖动的实例添加到设计器中.这些类中的每一个都定义了自定义属性:

[CompositeMetaData("Delay","Sets the delay between commands",1)]
[CompositeDesigner(typeof(DelayCompositeDesigner))]
public class DelayComposite : CompositeBase
{
}
Run Code Online (Sandbox Code Playgroud)

当用户选择设计器中的项目时,它会查看这些属性以便为该类型加载设计器.例如,在它的情​​况下,DelayComposite它将加载具有标签和滑块的用户控件,该标签和滑块允许用户设置DelayComposite实例的"延迟"属性.

到目前为止,如果我没有将任何参数传递给构造函数,这可以正常工作.设计者创建一个实例DelayCompositeDesigner并将其分配给WPF的content属性ContentPresenter.

但由于该设计人员需要在设计器中修改所选属性,因此DelayComposite 我必须将此实例传递给它.这就是为什么构造函数看起来像这样:

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;
}
Run Code Online (Sandbox Code Playgroud)

欢迎提出建议


@VolkerK

您的代码的结果是这样的:

<---- foo Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesignerVoid .ctor()Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesignerVoid .ctor(Vialis.LightLink.Controller.Scenarios.Composites.DelayComposite)param:Vialis .LightLink.Controller.Scenarios.Composites.DelayComposite foo ---->


Leppie,你是对的,我出于某种原因在我的UI应用程序中引用了Composites程序集......这不是我在运行时加载它时应该做的事情.以下代码有效:

object …
Run Code Online (Sandbox Code Playgroud)

.net c# activator missingmethodexception

18
推荐指数
3
解决办法
4万
查看次数

给定"where T:new()","new T()"在内部使用Activator.CreateInstance吗?

如果我有一个类型参数约束new():

void Foo<T>() where T : new()
{
    var t = new T();
}
Run Code Online (Sandbox Code Playgroud)

new T()内部使用该Activator.CreateInstance方法(即反射)是真的吗?

c# generics reflection activator type-constraints

14
推荐指数
1
解决办法
793
查看次数

我可以在界面中使用Activator.CreateInstance吗?

我有一个例子:

        Assembly asm = Assembly.Load("ClassLibrary1");
        Type ob = asm.GetType("ClassLibrary1.UserControl1");
        UserControl uc = (UserControl)Activator.CreateInstance(ob);
        grd.Children.Add(uc);
Run Code Online (Sandbox Code Playgroud)

我正在创建一个类的实例,但是如何创建实现某个接口的类的实例?即UserControl1实现ILoad接口.

U:我可以稍后将对象转换为接口,但我不知道程序集中的哪个类型实现了接口.

.net c# reflection activator .net-assembly

13
推荐指数
3
解决办法
2万
查看次数