首页 新闻 搜索 专区 学院

object转换为未知类型的List

0
悬赏园豆:100 [已解决问题] 解决于 2017-06-26 10:59

使用反射做一个根据sp名调用相应sp的方法,直接看代码

复制代码
public SUNCRM_GetAgentResult GetAgentBySPNameAndParam(string spName, string[] param, ref string pMsg) {
            SUNCRM_GetAgentResult _rtnList = new SUNCRM_GetAgentResult();
            try {
                Type type = typeof(Place_CRMDataContext);
                object reflectObj = Activator.CreateInstance(type);
                MethodInfo method = type.GetMethod(spName);
                object data = method.Invoke(reflectObj, param);//原始方法返回的是ISingleResult<具体类型>的对象,被转换为object了
        
        //使用这段代码替换下面的switch
                string attributeName = spName.Substring(15);
                PropertyInfo propertyInfo = typeof(SUNCRM_GetAgentResult).GetProperty(attributeName);
                object objData = Convert.ChangeType(data, propertyInfo.GetType());//报错,错误信息"对象必须实现 IConvertible"。
                propertyInfo.SetValue(_rtnList, objData);

                //switch是迫不得已的做法,如果以後增加了sp还要修改,虽然现在也还要修改模型类SUNCRM_GetAgentResult
                switch(spName) {    //有几十个sp,这里只列举几个
                    case "SUNCRM_GetAgentCodeIn":
                        _rtnList.CodeIn = ((ISingleResult<SUNCRM_GetAgentCodeInResult>)data).ToList();
                        break;
                    case "SUNCRM_GetAgentProfile":
                        _rtnList.Profile = ((ISingleResult<SUNCRM_GetAgentProfileResult>)data).ToList();
                        break;
                    case "SUNCRM_GetAgentFollow":
                        _rtnList.Follow = ((ISingleResult<SUNCRM_GetAgentFollowResult>)data).ToList();
                        break;
                    case "SUNCRM_GetAgentType_tags":
                        _rtnList.Type_tags = ((ISingleResult<SUNCRM_GetAgentType_tagsResult>)data).ToList();
                        break;
                }
                pMsg = spName;
                return _rtnList;
            } catch(Exception _ex) {
                pMsg ="sp name:" + spName + ",error message:" + _ex.Message;
                AcsUtils.WriteEvtLog(spName, _ex);
                throw new Exception(_ex.Message);
            }
            
        }
复制代码
问题补充:

现在最关键的问题是如何把原始类型为ISingleResult<具体类型>的object对象转换为List<具体对象>(这个具体类型是不确定的,参考switch)本来原始类型直接使用ToList()就能搞定,但是被转换为object了没有ToList()。

ISingleResult<具体类型> originalData = GetDataFromWcf();
object tempData = originalData;
List<具体类型> finalData = MyChangeType(tempData);

现在的问题是如何实现这个转换类型的MyChangeType()方法

补充:以下是属性名和sp名和具体类型的关系

属性名:"X"

sp名:"SUNCRM_GetAgent" + "X"

具体类型名:"SUNCRM_GetAgent" + "X" + "Result"

军长_cnblogs的主页 军长_cnblogs | 初学一级 | 园豆:18
提问于:2017-06-20 11:02
< >
分享
最佳答案
0

尝试各路方法无效,人工置顶一波,坐等大腿

军长_cnblogs | 初学一级 |园豆:18 | 2017-06-21 08:52

自己解決了,绕开了问题。原先SUNCRM_GetAgentResult中定义的都是List<具体类型>的属性,既然无法转换成list,那就定义成原始的ISingleResult<具体类型>的属性好了,反正客户端那边也是要调用ToList()方法的。这样拿到数据data后直接赋值就好,去掉数据转换的这行object objData = Convert.ChangeType(data, propertyInfo.GetType()),去掉整个switch,得到最终的代码。本质上还是没有解决标题所描述的问题,只是绕开了。

军长_cnblogs | 园豆:18 (初学一级) | 2017-06-26 10:54
其他回答(3)
0

用泛型?`

收获园豆:70
吴瑞祥 | 园豆:28831 (高人七级) | 2017-06-20 11:04

使用泛型的话传参是个问题,要根据sp名来传递不同的对象,这样还不如用switch。

支持(0) 反对(0) 军长_cnblogs | 园豆:18 (初学一级) | 2017-06-20 11:11

@军长_cnblogs: 不用泛型外面不知道是什么类型.

支持(0) 反对(0) 吴瑞祥 | 园豆:28831 (高人七级) | 2017-06-20 11:14

@吴瑞祥: 这是个wcf接口,接口调用方根据自己的需要从_rtnList中的具体属性获得值,参考switch,现在switch是已经暂时可以实现所要的效果的了。

支持(0) 反对(0) 军长_cnblogs | 园豆:18 (初学一级) | 2017-06-20 11:18
0

你说的十几个spName的话,用switch那一段写的太冗余了,传过来的spName可以放在同一个namespace下,通过反射全路径指向ISingleResult<typeOf(namespace路径.spName)>,这样可以不用switch。

收获园豆:20
柿子Boy | 园豆:256 (菜鸟二级) | 2017-06-20 15:38

能否给出代码?我试着这样写

object objData = (ISingleResult<typeof(SUNCRM_GetAgentCodeInResult)>)data;

vs会提示错误

支持(0) 反对(0) 军长_cnblogs | 园豆:18 (初学一级) | 2017-06-20 16:32
0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Type type = typeof(A);
            object reflectObj = Activator.CreateInstance(type);
            MethodInfo method = type.GetMethod("CCC");
            object data = method.Invoke(reflectObj,new string[]{"aaaaaaaaaa"});//原始方法返回的是ISingleResult<具体类型>的对象,被转换为object了

            if (data is IList<B>)
            {
                Console.WriteLine("这个是B类型");
            }

            if (data is IList<C>)
            {
                Console.WriteLine("这个是C类型");
            }
        }
    }


    class A
    {
        public IList<B> BBB(string h)
        {
            Console.WriteLine("AAAAAAAAAAAAAAA"+h);
            B b = new B();
            b.Name = "HelloWorld";

            List<B> list = new List<B>();
            list.Add(b);
            return list;
        }

        public IList<C> CCC(string h)
        {
            Console.WriteLine("AAAAAAAAAAAAAAA" + h);
            C b = new C();
            b.Name = "HelloWorld";

            List<C> list = new List<C>();
            list.Add(b);
            return list;
        }
    }

    public class B
    {
        public string Name { get; set; }
    }

    public class C
    {
        public string Name { get; set; }
    }
    public class D
    {
        public string Name { get; set; }
    }
}
收获园豆:10
田麦成 | 园豆:1984 (小虾三级) | 2017-06-21 17:59

有几十个类型的时候你这里不是要判断几十次。。。那感觉还不如switch

支持(0) 反对(0) 军长_cnblogs | 园豆:18 (初学一级) | 2017-06-22 16:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册