C# 在C中使用反射返回实例#
下面给出了我试图返回类实例的示例代码C# 在C中使用反射返回实例#,c#,asp.net,reflection,C#,Asp.net,Reflection,下面给出了我试图返回类实例的示例代码 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
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
我如何在这里提到类类型,因为在编译时不知道该类型,但它将在运行时确定。在上面的示例中,我只传递一个值1(可以是任何值,该类将被相应地调用),然后调用类test1
在这里,我将在objcls.callclass()
行中得到一个错误,因为objcls
是一个object
实例,它没有callclass()
方法
如何重构这段代码?我的目标是,如果我在getConstructorclass()
方法中提到一个类,那么应该返回一个对象,以便在进一步的代码中使用它来调用该类的成员。将变量声明为动态变量
无论
getconstrorclass
方法返回什么,都将在运行时使用该函数来确定。您可以访问该类型的任何成员,并且在编译时不会出现任何错误。但是,如果您试图访问一个不存在的成员,您将在运行时得到一个RuntimeBinderException
。如果您知道您的类将具有此方法,您应该为它们使用一个公共接口,并相应地实现它。然后,您将使用已确保其正常工作的类
看起来是这样的
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();
}
...
但它很快就会变得非常容易出错,重构可能是一场噩梦,等等,但这是你的决定
或者你们可以使用pwas的解决方案,但对我来说,对于这样一项基本任务来说,它似乎不必要地复杂。看起来不错,但它仍然只返回类型“object”,因此它并不能真正解决您的特定问题
另外,为了解决一个我不确定您是否理解的问题,您已经创建了实例,只需返回type object。这就是为什么你不能在这个对象上调用任何特定的方法,因为首先你必须将它强制转换为某个实际拥有该方法的对象,并确保可以执行强制转换(继承等)。不确定你最终想要实现什么,但这看起来像是“依赖注入”的工作-这里是一个使用的示例,我建议使用
接口
,并将您可以通过这种方式实例化的类限制为仅实现该接口的类
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();
}
公共接口IMyInterface
{
void callclass();
}
公共getConstructorClass()
{
T例;
Type Type=Type.GetType(“test1”);
//如果无法将对象转换为类型T,则实例将为null。
instance=Activator.CreateInstance(类型)作为T;
返回T;
}
IMyInterface objcls=getConstructorClass();
if(null!=objcls)
{
callclass();
}
如果接口
解决方案(见其他答案)足够,不要看这个答案。当您不能使用公共基类/接口并且仍然需要调用成员时,您可以使用带有is
关键字(和检查类型)的解决方案。您可以使用fluent API,而不是为每种情况编写许多ifs:
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();
objectobj=this.getConstructorclass();
obj.StronglyInvoke()
.When(value=>Console.WriteLine(“将{0}设为int”,value))
.When(value=>Console.WriteLine(“将{0}作为字符串,value))
.OnFail(()=>Debug.Write(“无句柄”))
.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);
}
}
公共类GenericCaller
{
私有IList调用程序=新列表();
私有只读对象目标;
私人行动;
公共GenericCaller(对象目标)
{
if(target==null)
{
抛出新的ArgumentNullException(“目标”);
}
this.target=目标;
}
公共GenericCaller OnFail(操作失败)
{
this.failAction=失败;
归还这个;
}
public GenericCaller When(然后执行操作)
{
if(then==null)
{
抛出新的ArgumentNullException(“then”);
}
var invoker=new GenericInvoker(然后是this.target);
this.invokers.Add(invoker);
归还这个;
}
公共无效调用()
{
if(this.invokers.Any(invoker=>invoker.Invoke())
{
返回;
}
if(this.failAction==null)
{
抛出新的InvalidOperationException(“未找到处理程序”);
}
这个.failAction();
}
公共抽象类GenericInvoker
{
受保护的只读对象目标;
受保护的GenericInvoker(对象目标)
{
this.target=目标;
}
公共抽象bool Invoke();
}
公共类GenericInvoker:GenericInvoker
{
私人只读操作;
公共GenericInvoker(对象目标,然后操作)
:基本(目标)
{
this.then=then;
}
公共重写bool Invoke()
{
if(this.target.GetType()==typeof(T))
{
然后((T)这个目标);
返回true;
}
返回false;
}
}
}
公共静态类扩展
{
公共静态GenericCaller StronglyInvoke(此对象为o)
{
返回新的GenericCaller(o);
}
}
请记住-使用通用界面(正如其他答案所说)会更优雅-我的方法是唯一的替代方法。我可以问一下,通过这样做,您想要实现什么吗?(顺便说一句,从你的例子中你知道
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);
}
}