[英]Activator.CreateInstance() troubles
I have a factory that is supposed to create objects that inherit from class Foo at run-time. 我有一个工厂应该创建在运行时从类Foo继承的对象。 I would think that System.Activator.CreateInstance's return type was the same as the type of an object it's creating, but judging from the following error message, its return type is Object. 我认为System.Activator.CreateInstance的返回类型与它创建的对象的类型相同,但从以下错误消息判断,其返回类型是Object。
Error 1 Cannot implicitly convert type 'object' to 'cs_sandbox.Foo'. 错误1无法将类型'object'隐式转换为'cs_sandbox.Foo'。 An explicit conversion exists (are you missing a cast?) F:\\projects\\cs_sandbox\\Form1.cs 46 24 cs_sandbox 存在显式转换(您是否缺少演员表?)F:\\ projects \\ cs_sandbox \\ Form1.cs 46 24 cs_sandbox
OK, so maybe I am missing a cast, but 好吧,也许我缺少一个演员,但
return (t)System.Activator.CreateInstance(t);
results in yet another error message, which -- I must admit -- makes no sense to me: 导致又一条错误信息 - 我必须承认 - 这对我没有意义:
Error 1 The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?) F:\\projects\\cs_sandbox\\Form1.cs 45 25 cs_sandbox 错误1找不到类型或命名空间名称't'(您是否缺少using指令或程序集引用?)F:\\ projects \\ cs_sandbox \\ Form1.cs 45 25 cs_sandbox
And here's my code: 这是我的代码:
class Foo { }
class FooChild1 : Foo { }
class FooChild2 : Foo { }
class MyFactory
{
public static Foo CreateInstance(string s)
{
Type t;
if (s.StartsWith("abcdef"))
{
t = typeof(FooChild1);
return System.Activator.CreateInstance(t);
}
else
{
t = typeof(FooChild2);
return System.Activator.CreateInstance(t);
}
}
}
How can I fix this code? 我该如何修复此代码? Or, if it's not fixable, what are other ways of creating objects that inherit from a specific class at run-time? 或者,如果它不可修复,那么在运行时创建从特定类继承的对象的其他方法是什么?
You need to cast the returned object to Foo
type. 您需要将返回的对象Foo
为Foo
类型。 It doesn't make sense to cast it to a type defined in a variable. 将它强制转换为变量中定义的类型是没有意义的。 It should be known by the compiler, as the whole point of casting through the inheritance hierarchy is satisfying compiler's static type checking. 它应该由编译器知道,因为通过继承层次结构的整个点是满足编译器的静态类型检查。
return (Foo)System.Activator.CreateInstance(t);
There's a generic version, System.Activator.CreateInstance<T>
, which creates a known type (not a type variable but a type argument or a statically known type, in the latter case, it doesn't make much sense though): 有一个通用版本, System.Activator.CreateInstance<T>
,它创建一个已知类型(不是类型变量,但是类型参数或静态已知类型,在后一种情况下,它没有多大意义):
return System.Activator.CreateInstance<FooChild1>();
I had to use to UnWrap() method after activating, like described on MSDN: 我必须在激活后使用UnWrap()方法,如MSDN中所述:
// Creates an instance of MyType defined in the assembly called ObjectHandleAssembly.
ObjectHandle obj = domain.CreateInstance("ObjectHandleAssembly", "MyType");
// Unwrapps the proxy to the MyType object created in the other AppDomain.
MyType testObj = (MyType)obj.Unwrap();
As described on MSDN . 如MSDN所述 。 Furthermore, I had to use parameters like this: 此外,我不得不使用这样的参数:
ObjectHandle obj = domain.CreateInstance("Other.Assembly.Name", "Full.Class.Namespace.ClassName");
Just cast your results to Foo
like 只需将结果投射到Foo
就好了
return System.Activator.CreateInstance(t) as Foo;
or 要么
return (Foo)System.Activator.CreateInstance(t);
The first one is a bit more robust because you won't get an exception in case cast is not possible. 第一个更健壮,因为在不可能的情况下你不会得到异常。 It will simply return null
. 它只会返回null
。 But it depends what you want. 但这取决于你想要什么。
Have you tried generics?
你尝试过泛型吗?
public static OutType CreateInstance<OutType>(string s)
{
Type t;
if (s.StartsWith("abcdef"))
{
t = typeof(Bar);
return System.Activator.CreateInstance(t) as OutType;
}
else
{
t = typeof(Meh);
return System.Activator.CreateInstance(t) as OutType;
}
}
But you do have a problem.
但你确实有问题。
In your existing static method you are trying to return
Bar
and
Meh
that aren't related to
Foo
in any way.
在您现有的静态方法中,您试图以任何方式返回与
Foo
无关的
Bar
和
Meh
。
This will always be an exception unless your method also returns an object or a common ancestor type (as in casting).
除非您的方法还返回一个对象或一个共同的祖先类型(如在转换中),否则这将始终是一个例外。
To control even more internal types you could define more than one generic type that your method would use internally.
要控制更多内部类型,您可以定义方法在内部使用的多个泛型类型。
I think you should probably do this: 我想你应该这样做:
public static Foo CreateInstance(string objectIdentifer)
{
if (objectIdentifier == "Child1")
{
return (Foo)Activator.CreateInstance("Foo.FooChild1, FooChild1");
}
else
{
return (Foo)Activator.CreateInstance("Foo.FooChild1, FooChild2");
}
}
My point is that in this code, the CreateInstance method has no direct reference to the assembly or assemblies containing FooChild1 and FooChild2. 我的观点是,在此代码中,CreateInstance方法没有直接引用包含FooChild1和FooChild2的程序集。 In the original code, you create a type by explicitly naming FooChild1 and FooChild2, so you might as well just new them instead of activating them. 在原始代码中,您通过显式命名FooChild1和FooChild2来创建类型,因此您可能只是新建它们而不是激活它们。
Does this make sense to you? 你能理解这个吗?
I think the correct is: 我认为正确的是:
public static Foo CreateInstance(string objectIdentifer)
{
if (objectIdentifier == "Child1")
{
return (Foo)Activator.CreateInstance(Type.GetType("Foo.FooChild1, FooChild1"));
}
else
{
return (Foo)Activator.CreateInstance(Type.GetType("Foo.FooChild1, FooChild2"));
}
}
Hope that can help you 希望能帮到你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.