如何通过反射访问Items.Clear() [英] How to get access Items.Clear() through reflection

查看:78
本文介绍了如何通过反射访问Items.Clear()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我正在尝试从listBox或comboBox访问Clear()方法。



我已经完全按照以下示例:



  //   aListBox ==我的表单中的listBox  

var propertyFromControl = aListBox.GetType()。GetProperty( Items);





问题是,对于我的项目,我将接收一组控件,其中一些将具有带Clear的Items属性( ) 方法。是否可以访问/执行此Clear()?



  //  非实际代码 

var propertyFromControl = aListBox.GetType()。 GetProperty( Items);

var methodFromProperty = propertyFromControl.GetMethod( 清除);

// 这里让人感到困惑
methodFromProperty。 execute(propertyFromControl, null ); // 如何指向它到原来的aListBox





我希望提供足够的信息。



关于

解决方案

看看这是否有助于你开始。将一个名为listBox1的ListBox放在表单上,​​添加以下方法:

  //  必需 
使用 System.Reflection;

private void ClearListBox()
{
控制theControl = listBox1;

类型cType = theControl.GetType();

PropertyInfo [] cProps = cType.GetProperties();

PropertyInfo targetProperty = null ;

类型targetType = typeof (ListBox.ObjectCollection);

foreach (PropertyInfo cProp in cProps)
{
if (cProp.Name == Items && cProp.PropertyType == targetType)
{

targetProperty = cProp;
break ;
}
}

如果(targetProperty!= null
{
object items = targetProperty.GetValue(theControl, null );
MethodInfo clear = targetProperty.PropertyType.GetMethod( Clear);
if (clear!= null )clear.Invoke(items,);
}
}

当然,这是特定于ListBox的,但它演示了调用'使用反射清除'时需要采取的步骤。您可以通过编写代码来扩展它,以处理具有不同类型的Item集合的其他控件的各种情况,例如ComboBox(ComboBox.ObjectCollection),ListView(ListViewItemCollection)等。


< blockquote>

PauloAugustoKünzel写道:

谢谢,但我已经被困在正确的轨道上超过几天了。我既找不到材料,也找不到能帮助我的人。这有点令人沮丧。

我再说一遍,这很容易。看,如果你想练习,一些随时可用的代码示例将不允许你根据自己的经验练习,几乎没用。这就是为什么我不想为你编写代码。为了真正提供帮助,我想给你一些提示,因为我知道有些人通常会卡在哪里。



除了常规的MSDN文档之外,我从未使用任何东西;所以你也不需要别的东西,按照定义行事。



你有两种类型,属性类型和列表框类型;你需要反映两者。您反映列表框的类型,获取Items属性的实例。这是通过调用属性getter来完成的。 (难以猜到吗?这一点可能是你卡住的原因。调用getter。)你已经有了列表框的实例,所以用它来传递给getter,这是一个实例(非静态)方法。



当你得到 Items 属性的实例时,它是是时候忘记列表框的实例了。反映 Items 的类型,找到所需的方法。这当然也是实例方法,所以要调用它,你需要传递你在下一步获得的 Items 的实例。



所以,除了你已经找到的东西,你需要学习如何获得一个访问者(getter):http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.getmethod.aspx [ ^ ]。







类似于:

< pre lang =c#> PropertyInfo pi = // ...说,你有一个属性信息Items
MethodInfo mi = pi.GetMethod;
object itemsInstance = mi.Invoke( / * ... * / );
// ...





[结束编辑]



您还需要知道如何调用实例方法:

http://msdn.microsoft.com/en-us/library /a89hcwhh%28v=vs.110%29.aspx [ ^ ],

http://msdn.microsoft.com/en-us/library/4k9x6bc0%28v=vs.110%29.aspx [ ^ ]。



在调用方法时,请注意参数 Object obj 。这是你传递调用方法的对象实例的方法(方法实现中的this引用)。



所有这些真的很容易。你会看到。



现在,在实践中,你应该明白使用反射通过代表名称的某个字符串来查找任何东西是一种不好的做法(需要它,比如,实现IDE 设计器,因为这样的解决方案是不可支持的。想象一下,如果重命名某个方法或者只是用方法名称拼错字符串会发生什么。编译器不会检测到问题,但此类解决方案将停止工作。一种强大的方法是找到由接口定义找到的某个类/结构实现的接口,而不是通过其名称。你可以相当安全地调用这种类型实例的接口方法。



-SA


Hi,

I'm trying to access the method Clear() from a listBox or a comboBox.

I've maanged to go as far as the example below:

// aListBox == A listBox in my form

var propertyFromControl = aListBox.GetType().GetProperty("Items");



The thing is that, for my project I'll be receiving a group of controls, and some of them will have a Items property with the Clear() method. Is it possible to access/execute this Clear()?

// Not Actual code

var propertyFromControl = aListBox.GetType().GetProperty("Items");

var methodFromProperty = propertyFromControl.GetMethod("Clear");

//here is where it gets confusing
methodFromProperty.execute(propertyFromControl, null);//how to point it to the original aListBox



I hope to have provided enough information.

regards

解决方案

See if this helps you get going. Put a ListBox, named 'listBox1, on a Form, add this method:

// required
using System.Reflection;

private void ClearListBox()
{
    Control theControl = listBox1;

    Type cType = theControl.GetType();

    PropertyInfo[] cProps = cType.GetProperties();

    PropertyInfo targetProperty = null;

    Type targetType = typeof (ListBox.ObjectCollection);

    foreach (PropertyInfo cProp in cProps)
    {
        if (cProp.Name == "Items" && cProp.PropertyType == targetType)
        {
            
            targetProperty = cProp;
            break;
        }
    }

    if (targetProperty != null)
    {
        object items = targetProperty.GetValue(theControl, null);
        MethodInfo clear = targetProperty.PropertyType.GetMethod("Clear");
        if(clear != null) clear.Invoke(items, null);
    }
}

Of course, this is specific to a ListBox, but it demonstrates the steps you'll need to take to invoke 'Clear using reflection. You can extend this by writing code to handle the various cases of other Controls that have Item collections of varying Types, such as the ComboBox (ComboBox.ObjectCollection), the ListView (ListViewItemCollection), etc.


Paulo Augusto Künzel wrote:

Thanks, but I've been on stuck on the right track for over a couple days. I can't find neither material nor people that can help me. It is getting a bit frustrating.

I repeat, that is quite easy. Look, if you want to practice, some ready-to-use code sample will not allow you to practice on your own experience, will be nearly useless. That's why I don't want to write the code for you. To really help, I want to give you some hints, because I know where some people typically got stuck.

I never used anything but regular MSDN documentation; so you, too, don't need anything else, just act by definition.

You have two types, property type and list box type; you need to reflect both. You reflect the type of the list box, get instance of the Items property. This is done by invocation of the property getter. (Was that so hard to guess? This point could be a reason why you stuck. Call the getter.) You already have the instance of the list box, so use it to pass to the getter, which is an instance (non-static) method.

When you got an instance of the Items property, it's time to forget the instance of the list box. Reflect the type of Items and find the method you want. This is of course also the instance method, so to call it, you need to pass the instance of the Items you obtained on the next step.

So, in addition to what you already found, you need to learn how to get an accessor ("getter"): http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.getmethod.aspx[^].

[EDIT]

Something like:

PropertyInfo pi = //... say, you got a property info of "Items"
MethodInfo mi = pi.GetMethod;
object itemsInstance = mi.Invoke(/* ... */);
//...



[END EDIT]

And you also need to know how to invoke an instance method:
http://msdn.microsoft.com/en-us/library/a89hcwhh%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/4k9x6bc0%28v=vs.110%29.aspx[^].

In invocation of the method, pay attention for the parameter Object obj. This is how you pass the instance of the object on which you invoke the method ("this" reference in the method implementation).

All this is really, really easy. You will see.

Now, in practice, you should understand that using reflection to find anything by some string representing the name is a bad practice (it is needed in, say, implementation of the IDE designers though), because such solutions are not supportable. Imagine what can happen if you rename some method or simply misspell the string with a method name. The compiler won't detect a problem, but such solution will stop working. One robust approach is finding an interface implemented by some class/structure, found by interface definition, not by its name. Than you can call interface method of this type instance quite safely.

—SA


这篇关于如何通过反射访问Items.Clear()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆