/// <summary>
        /// 获取得到值以后的 泛型数组
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="SQL"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public List<T> getModelList<T>(string SQL, List<string> list)where T:class,new()
        {
            try
            {
                List<T> Mlist = new List<T>();
                IDataReader dr = getDataReader(SQL, list);
                while (dr.Read())
                {
                    T obj = new T();
                    obj = this.LoadFromReader<T>(dr);
                    Mlist.Add(obj);
                }
                return Mlist;
            }
            catch (Exception ex)
            {
                return null;
            }
        }WCF编译时,出现如下错误
类型“System.Collections.Generic.List`1[T]”无法作为架构类型被导出,因为它是一种开放的泛型类型。泛型类型仅可以在其所有的泛型参数类型均为实际类型时才可以被导出。 寻求解决办法

解决方案 »

  1.   

    统一出来一个INTERFACE,让T限制在此INTERFACE内。然后加SERVICEKNOWNTYPEATTRIBUTE就行了。
      

  2.   

    WCF不能使用泛型方法,不支持。只能使用变通的方法实现,传递Type参数代表T的类型。
      

  3.   

    楼主人呢?
    要不要帮你把那个泛型方法改写成可以给WCF调用的非泛型方法形式,且功能不变?
      

  4.   

    呵呵,不好意思,昨天下班了,我不是很明白你所说的变通方法传递Type的意思,我这个泛型方法的初衷是可以传入任意的Model类型  
      

  5.   

    范型方法。用代码方式实现WCF配置
     
        public class ConManager
        {
            NetTcpBinding netTcpBinding = null;
            ServiceEndpoint serviceEndpoint = null;
            EndpointAddress endpointAddress = null;
            InstanceContext instanceContext = null;
            public DuplexChannelFactory<T> WCFconfig<T>(long maxReceivedMessageSize, TransferMode transferMode)
            {
                netTcpBinding = new NetTcpBinding();
                netTcpBinding.MaxReceivedMessageSize = maxReceivedMessageSize;
                netTcpBinding.TransferMode = transferMode;
                ContractDescription cd = ContractDescription.GetContract(typeof(T));            serviceEndpoint = new ServiceEndpoint(cd);
                serviceEndpoint.Address = new EndpointAddress("");
                serviceEndpoint.Binding = netTcpBinding;            
                instanceContext = new InstanceContext(this);
                DuplexChannelFactory<T> factory = new DuplexChannelFactory<T>(instanceContext, serviceEndpoint);
                return factory;
            }
        }
      

  6.   

    不好意思,昨天下班了,我想知道你说的那个变通方法,我这个方法的初衷是可以适合任意的实体类型,传入相应的SQL语句以及任意的参数返回一个泛型数组
      

  7.   

    WCF能支持泛型吗?lz解决了上来吱一声。
      

  8.   

    楼主  能否将你的this.LoadFromReader<T>(dr);方法粘贴出来
      

  9.   

    这个方法应该跟该问题没啥关系的        protected T LoadFromReader<T>(IDataReader reader) where T : class,new()
            {
                try
                {
                    T obj = new T();
                    Type type = obj.GetType();
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        PropertyInfo prop = type.GetProperty(reader.GetName(i));
                        if (prop != null && reader.GetValue(i) != DBNull.Value)
                        {
                            try
                            {
                                prop.SetValue(obj, reader.GetValue(i), null);
                            }
                            catch (Exception)
                            {
                                continue;
                            }
                        }
                    }
                    return obj;
                }
                catch
                {
                    return null;
                }
            }
      

  10.   

    我觉得是不太可能的,因为参数和返回值需要在wsdl中描述,不确定的话,也就没有办法描述了。
      

  11.   

    呵呵,我知道这一点违背了WCF的面向服务的原则, 只是想尝试下,我感觉这样如果能够使用的话那么科室省掉很多的事。
      

  12.   

    不知道是我想简单了,还是你想的复杂了。我认为能解决问题就行,当然我用的不是WCF。我现在的实现仅仅是传了个Type.FullName和Assembly.FullName,当然还可以把Assembly.Location传过去处理文件。using System;
    using System.Reflection;namespace showjim.setup.cSharp
    {
        [showjim.setup.attribute.serialize(isMemberEnum = false)]
        public partial class type
        {
            public string name;
            public string assemblyName;
            public Type value
            {
                get
                {
                    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                    {
                        if (assembly.FullName == assemblyName)
                        {
                            Type type = assembly.GetType(name);
                            if (type != null) return type;
                        }
                    }
                    showjim.sys.debug.message("未能加载类型 : " + name + " in " + assemblyName).throwException();
                    return null;
                }
            }
            public type(Type type)
            {
                name = type.FullName;
                assemblyName = type.Assembly.FullName;
            }
        }
    }模板里面的参数生成                            _genericTypes_ = new showjim.setup.cSharp.type[]
                                {
                                    #region LOOP genericParameters
                                    new showjim.setup.cSharp.type(typeof(@genericParameterTypeName))/*NOT:isLast*/,/*NOT:isLast*/
                                    #endregion LOOP genericParameters
                                },模板里面的最终调用                    #region IF method.IsGenericMethod
                        private static System.Reflection.MethodInfo @genericIndexName = showjim.sys.reflection.methodInfo.getGenericDefinition<showjim.setup.attribute.tcpCall>(typeof(@codeType.fullName).GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic), method => method.IsGenericMethod && method.Name == "@methodName" /*IF:isMethodReturn*/ && method.ReturnType != typeof(void)/*IF:isMethodReturn*//*Not:isMethodReturn*/ && method.ReturnType == typeof(void)/*Not:isMethodReturn*/ && method.GetParameters().Length == @methodParameterCount);
                        public static object @methodIndexName(Type[] types, params object[] parameters)
                        {
                            if (@genericIndexName == null) showjim.sys.debug.message(null).throwException();
                            return @genericIndexName/**/.MakeGenericMethod(types).Invoke(null, parameters);
                        }
                        #endregion IF method.IsGenericMethod对于函数我没有处理相同参数数量重载的情况,因为现在还没用到。
      

  13.   

    抱歉,最近太忙了,还要去医院挂水,没什么时间。方案已经设计好,下面给你代码:public IList getModelList(string type, string SQL, List<string> list)
    {
        try
        {
            IList Mlist = new List<object>();
            IDataReader dr = getDataReader(SQL, list);
            while (dr.Read())
            {
                object obj = this.GetType().GetMethods().First((p) => p.IsGenericMethod && p.Name == "LoadFromReader").MakeGenericMethod(Helper.types[type]).Invoke(this, new object[] { dr });
                Mlist.Add(obj);
            }
            return Mlist;
        }
        catch (Exception ex)
        {
            return null;
        }
    }接口:
    [OperationContract]
    [ServiceKnownType("GetKnownTypes", typeof(Helper))]
    IList getModelList(string type, string SQL, List<string> list);
    Helper类的定义(这是关键):    public static class Helper
        {
            public static Dictionary<string, Type> types = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "XXX.Model.dll").GetTypes().ToDictionary(t => t.Name);        public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
            {
                return types.Select(t=>t.Value);
            }
        }
    上面的Helper类,调用了一个实体类的程序集XXX.Model.dll,你必须要将所有实体类单独做到一个项目中并编译到dll文件,然后通过dll文件名加载里面所有类型,否则就需要手动添加一个个实体类到那个types变量中。
      

  14.   

    那个while (dr.Read())里面其实应该优化下,把那个反射放到外面后,内部调用,这样不需要重复反射,可增加效率。
      

  15.   


    这两天我身体也不好在调休,没能及时回复,还是谢谢您能抽空给我解答,上面的代码我刚看了下,我觉得那个实体类独立编译成dll不现实,我写这个方法的目的就是希望在添加新的实体类的时候不需要去改动服务端的代码  
      

  16.   

    我给你解决了泛型方法的WCF调用,不代表给你解决了动态添加实体类,WCF的所有调用都必须是已知类型,对于动态添加的实体类,如果必须要实现就必须通过已知类型来进行转换处理,这又是另一个话题了。17楼的代码我也看过,对你一点帮助都没有。理由一:他的代码并非用在WCF上面的;理由二:他小看了WCF,从18楼的回复也可以看出,以为调用时的泛型类型确定了,就可以用在WCF上面,而那个必须要定义时就确定,否则无法使用WSDL描述。理由三:WCF除了不支持泛型外,还不支持部分可序列化的类型,虽然Type类型可序列化,但是不能用在WCF上面,因为实际是通过RuntimeTypeHandle来传递的,但是那个跨进程就不一样了,属于本地句柄。
      

  17.   

    我不是来解决楼主问题的,我的回答是对15#的回复,实践证明网络泛型调用时可行的。至于WCF是否支持,为什么我并不关心。
    小看WCF?在我眼里,WCF还真不是什么好东西。
    你的意思是说网络调用支持泛型反而是不应该的了?支持部分序列化也是不应该的?可笑
      

  18.   

    那么请你把这个泛型调用的说明放上去,你给的代码里只有对type类型的传递处理,没有泛型T的的处理说明,哪里看出你有用在泛型处理上面了?
      

  19.   

            static T Get<T>(T a)
            {
                return a;
            }泛型函数调用的全写是
                int a = 1;
                a = Get<int>(a);简写
                int a = 1;
                a = Get(a);不要被简写搞迷惑了。
      

  20.   

    看来是你自己没搞明白,我总算看明白你的代码了,和我的思路完全一样,通过反射方法名创建泛型的MethodInfo,运行时设置泛型类型后Invoke。但是你没有搞清楚2点,第一:你的方法就是我所谓的变通方法,而不是WCF理所当然必须支持的方法,所以你看不起WCF是没道理的,你所使用的场合也是不支持泛型了才用到这个变通方法。第二:你直接将所谓的模板放上,模板这东西不在一个配置好的环境中是不能直接运行的,代码原理和我的一致,你仔细看19楼我的代码,我还增加的WCF必须的处理过程,但你的代码是无法直接在WCF中使用的,对楼主帮助不大也没说错。
      

  21.   

     _genericTypes_ = new showjim.setup.cSharp.type[]
                                {
                                    #region LOOP genericParameters
                                    new showjim.setup.cSharp.type(typeof(@genericParameterTypeName))/*NOT:isLast*/,/*NOT:isLast*/
                                    #endregion LOOP genericParameters
                                },
    17#那段模板你看不明白,那就上一段生成好的测试代码给你看
    _genericTypes_ = new showjim.setup.cSharp.type[]
                                {
                                    new showjim.setup.cSharp.type(typeof(valueType)),
                                    
                                    new showjim.setup.cSharp.type(typeof(valueType1))
                                    
                                },
      

  22.   

    看明白了,我是看到return @genericIndexName/**/.MakeGenericMethod(types).Invoke(null, parameters);
    这段才看明白的,因为你的命名规则实在别扭,第一次见到用@符号开头的变量名,所以一直被我pass了。
      

  23.   

    我从来就没有说过WCF要不要支持,我只是强调网络泛型调用是可行的。
    我也不用WCF,在我看来,那个操作契约就是多余的工作。下面分别是泛型的同步于异步调用。namespace showjim.setup.cSharp.test
    {
        [showjim.setup.attribute.tcpCall(server = showjim.config.tcpCall.server.enumType.dataProxy)]
        public partial class TcpCall
        {
            [showjim.setup.attribute.tcpCall]
            private static valueType generic<valueType, valueType1>(valueType value, ref valueType1 refValue, out valueType outValue)
            {
                return outValue = value;
            }
            [showjim.setup.attribute.tcpCall]
            private static void generic<valueType, valueType1>(showjim.setup.coder.AsyncMethodParameter<valueType1> onMethod, valueType value, ref valueType1 refValue, out valueType outValue)
            {
                outValue = value;
            }
        }
    } int a = 0, c;
                string b = null;
                int d = showjim.setup.cSharp.test.TcpCall.tcpCall.client.generic(a, ref b, out c);
      

  24.   

    请问你用的又是什么呢?是比WCF强大?还是比WCF简单?或是通用性更强?
      

  25.   

    我用的是代码生成,性能、人性化、易用性、灵活性都比WCF强。
    缺点是通讯机制少(目前只支持TCP),我一直只用TCP,我是用到什么写什么。
      

  26.   

    我这么理解不知道对不对,你这个是基于Socket的自定义TCP传输,消息并未遵循SOAP规范,因此无法跨平台调用。
      

  27.   

    是否遵循SOAP规范也是各有优缺点的,遵循SOAP规范的程序不可能做更底层协议的事情。比如http://www.51nod.com/today.html#!type=这样web服务器就没法做。
      

  28.   

    我晕...WCF 怎么会支持泛型了。。如果真要这样  你可以定义一个class  一个是model的枚举类型,一个是byte[] 或者string  序列化 和反序列,,,说的很简单。。如果 你懂的话 就明白了
      

  29.   

    object obj = this.GetType().GetMethods().First((p) => p.IsGenericMethod && p.Name == "LoadFromReader").MakeGenericMethod(Helper.types["ModelDb"]).Invoke(this, new object[] { dr });
      中 LoadFromReader   啥意思?