我试图返回类的实例,示例代码如下所示。
public object getConstructorclass(int i)
{
if(i==1)
{
Type type = Type.GetType("test1");
}else
{
Type type = Type.GetType("test2");
}
return Activator.CreateInstance(type);
}
var objcls = getConstructorclass(1);
objcls.callclass();//error occured
我怎么能在这里提到的类类型,因为该类型不是在编译时已知的,但它会在runtime.In决定上面的例子中,我传递的值1(它可以是任何东西,则该类将相应地调用),和类test1的调用。
在这里,我将获得上线一个错误objcls.callclass()
因为objcls
是一个object
不具有一个实例callclass()
方法。
我怎么能重组这段代码? 我的目标是,如果我在提及一类getConstructorclass()
方法,对象应返回,以便使用它的进一步代码来调用该类别的成员。
如果你知道你的类都会有这样的方法,你应该使用他们共同的界面和遵照执行。 然后,你将用你已经确信它会工作类的工作。
它看起来像这样
IMyInterface objcls = getconstrorclass() as IMyInterface;
if (objcls != null)
objcls.callclass();
else
// we failed miserably and should do something about it
我不认为你应该使用基于int变量一些通用的对象返回的构造函数,如果你的类没有什么共同点。 这真是奇怪处理它这样,它可能导致各种问题(其中一些您目前已经出现了)。 通用类的构造函数意义,如果这些类有点关系,你可以预测的结果,而是创造一个做它,所有的方法..不那么肯定这种做法的正确性。
无论如何,如果你坚持(不推荐,但你愿意的话),你可以创建一个类型一些像这样的检查:
var createdObject = getConstructorclass(1);
if (createdObject is MyClass1)
{
var specificObject = (MyClass1)createdObject;
specificObject.callMethod1();
}
else if (createdObject is MyClass2)
{
var specificObject = (MyClass2)createdObject;
specificObject.callSomeOtherMethod();
}
...
但它得到很快容易出错,重构将可能是一场噩梦等,但它是你的电话..
或者,你也许可以从使用的PWA的解决方案,但对我来说,似乎对于这样的基本任务不必要地复杂化。 看起来不错,所有的,但它仍然只返回类型的“对象”,所以它并没有真正解决您的具体问题。
此外,为了解决一个问题,我不知道你明白 - 你已经创建的实例,你可以返回类型的对象。 这就是为什么你不能调用这个对象上的任何具体的方法,因为首先你必须将它转换的东西,实际上有一个方法,并确保铸件可以做到的(继承等)。
如果interface
解决方案(见其他答案)就足够了,不要看这个答案。 当你不能用普通的基类/接口,你仍然要调用的成员,您可以使用解决方案与is
关键字(检查类型)。 而不是写很多IFS为每种情况下,你可以用流利的API:
object obj = this.getConstructorclass();
obj.StronglyInvoke()
.When<int>(value => Console.WriteLine("Got {0} as int", value))
.When<string>(value => Console.WriteLine("Got {0} as string", value))
.OnFail(() => Debug.Write("No handle."))
.Invoke();
解:
public class GenericCaller
{
private IList<GenericInvoker> invokers = new List<GenericInvoker>();
private readonly object target;
private Action failAction;
public GenericCaller(object target)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
this.target = target;
}
public GenericCaller OnFail(Action fail)
{
this.failAction = fail;
return this;
}
public GenericCaller When<T>(Action<T> then)
{
if (then == null)
{
throw new ArgumentNullException("then");
}
var invoker = new GenericInvoker<T>(this.target, then);
this.invokers.Add(invoker);
return this;
}
public void Invoke()
{
if (this.invokers.Any(invoker => invoker.Invoke()))
{
return;
}
if (this.failAction == null)
{
throw new InvalidOperationException("Handler not found");
}
this.failAction();
}
public abstract class GenericInvoker
{
protected readonly object target;
protected GenericInvoker(object target)
{
this.target = target;
}
public abstract bool Invoke();
}
public class GenericInvoker<T> : GenericInvoker
{
private readonly Action<T> then;
public GenericInvoker(object target, Action<T> then)
: base(target)
{
this.then = then;
}
public override bool Invoke()
{
if (this.target.GetType() == typeof(T))
{
this.then((T)this.target);
return true;
}
return false;
}
}
}
public static class Extensions
{
public static GenericCaller StronglyInvoke(this object o)
{
return new GenericCaller(o);
}
}
Remeber -这将是更优雅的使用通用接口(如其他答案说) -我只是另一种方式。
声明你的变量动态
dynamic objcls = getconstrorclass();
使用这个会在运行时,无论确定getconstrorclass
方法返回。 您可以访问该类型的任何成员,您将无法获得在编译时的错误。 但是,如果您尝试访问不存在,你会得到一个成员RuntimeBinderException
在运行时。
我会建议使用的interface
和限制,你可以用这种方式实例化,只有那些实现该接口的类。
public interface IMyInterface
{
void callclass();
}
public <T> getConstructorClass()
{
T instance;
Type type = Type.GetType("test1");
// instance will be null if the object cannot be cast to type T.
instance = Activator.CreateInstance(type) as T;
return T;
}
IMyInterface objcls = getConstructorClass<IMyInterface>();
if(null != objcls)
{
objcls.callclass();
}
不知道你想要什么,最终实现,但这个看起来像“依赖注入”工作-这里是一个很好的样本使用autofac