1

我对自动取款机有点困惑,我认为这不会这么难,因为那时我一定做错了什么。在过去的 2 天里,我现在要做的是访问存储在 List 中的对象内部的方法,但我无法理解它。在我看来,它应该只是让对象恢复其原始类型并调用该方法,但我就是做不到。

我一直在阅读很多关于类型、泛型和反射的内容,但它无法正常工作,所以我显然做错了,我需要帮助找到光!

这是我尝试过的最新代码

            Object customer = Hotel.Main.Manager.GetMainList(x);
            Type frsttype = customer.GetType();              
            MethodInfo method = frsttype.GetMethod("GetCustomerSpecificData");
            MethodInfo generic = method.MakeGenericMethod(frsttype);
            String str = generic.Invoke(method);

我想要达到的是对象内部的这个方法:

            public override string GetCustomerSpecificData()
    {
        string strout = string.Format("{0,-5}{1,26}{2,28}{3,28}\a", ID, Name, Age, Gender);

        string strInfo = Extra;
        strout += (string.IsNullOrEmpty(strInfo) ? string.Empty : strInfo);

        if (m_specialoffer)
        {
            strout += string.Format("\nSpecial Offer");
        }
        if (IsRegularCustomer)
        {
            strout += (IsDangerus ? "\nIs a regular customer " : "\nIs not a regular customer.");
        }
        strout += Environment.NewLine + PaymentInfo();
        strout += (m_CarPark ? "\nHas car parked in garage." : "\nDoes not have car parked in garage.");
        return strout;
    }

我希望有人能指出我正确的方向,因为我认为我在这个方面没有任何进展:/

任何帮助和提示将不胜感激!!!所有的回复都会被点赞!

问候

4

3 回答 3

4

这里有几件事你需要做,首先让我们看看你发布的代码

您不需要问自己的第一个问题是我是否需要使用反射,我可以使用接口或返回我知道的类型吗?

您是否可以控制 GetMainList(x)?如果是这样,你不能改变它,让它返回比对象更有用的东西吗?

Object customer = Hotel.Main.Manager.GetMainList(x);

你能投射到任何东西吗?

其次,您的目标方法不是通用方法,因此下面的行不起作用。

MethodInfo generic = method.MakeGenericMethod(frsttype);

您还错误地调用了该方法,您 Invoke 有两个参数,第一个是您希望调用该方法的目标对象以及您可以传递给它的参数。

Invoke(object obj, object[] parameters)

要调用您的方法,您需要执行以下操作。

Object customer = Hotel.Main.Manager.GetMainList(x);
Type frsttype = customer.GetType();
MethodInfo method = frsttype.GetMethod("GetCustomerSpecificData");
String str = method.Invoke(customer, null) as string;

stackoverflow 上有一些很棒的问题和社区 wiki,当然 MSDN 库中有很多教程和示例。

可以在下面找到一个很好的 .net 反射教程。

于 2013-03-09T10:38:06.947 回答
3

我的意思是你可以很容易地调用它:

 Type myType =customer.GetType();
 MethodInfo method = typeof(customer).GetMethod("GetCustomerSpecificData");
 MethodInfo generic = method.MakeGenericMethod(myType);
 var res= generic.Invoke(this, null);
于 2013-03-09T10:43:45.513 回答
2

最接近您目前拥有的内容可以在不依赖反射的情况下工作。

Object customer = Hotel.Main.Manager.GetMainList(x);

string result="";
var custObj = customer as Customer;
if (custObj !=null)
{
    result = custObj.GetCustomerSpecificData();
}

var specialcustObj = customer as SpecialCustomer;
if (specialcustObj !=null)
{
   result = specialcustObj.GetCustomerSpecificData();
}

/* etc */

或者,如果你可以改变List中不同类型的实现有一个接口(或者替代一个(抽象)基类。

/* alternatively name it ISpecificData if you want adhere common used standards */
public interface SpecificData
{
     string GetCustomerSpecificData();
}

对于您的客户和其他可以在列表中的类:

public class Customer:SpecificData
{
   /* rest of implemementastion stays the same */
}

您获取客户的代码将如下所示,并且适用于列表中实现该接口的每个对象。

Object customer = Hotel.Main.Manager.GetMainList(x);

string result="";
var interfaceObj = customer as SpecificData;
if (interfaceObj != null) 
{
  result = interfaceObj.GetCustomerSpecificData();
}

当您知道列表中只有一个特定接口时,您可以使用通用列表来仅保存该特定类型的对象:

mainlist = new List<SpecificData>();

并且您可以调整 GetMainList 以仅返回接口 SpecificData

于 2013-03-09T11:16:50.677 回答