【问题标题】:Generic Method, Generic Type, Generic Parameter泛型方法、泛型类型、泛型参数
【发布时间】:2011-11-15 19:31:36
【问题描述】:

我什至不确定如何描述我正在尝试做的事情(抱歉,新手),但是因为我还没有弄清楚如何正确地做而复制代码在我的列表中并不重要。请帮忙?

原始的非泛型方法:

    public static string SerializetaUpdateCreateItemRcd(IVItemMasterType o)
    {
        eConnectType eConnect = new eConnectType();

        IVItemMasterType[] myMaster = { o };

        // Populate the eConnectType object with the schema object
        eConnect.IVItemMasterType = myMaster;

        return MemoryStreamSerializer(eConnect);
    }

我对通用的尝试,如此接近,在设置类型属性时迷失了(?):

    public static string Serialize<T>(T o) where T : eConnectType
    {
        eConnectType eConnect = new eConnectType();

        T[] myMaster = { o };

        // Populate the eConnectType object with the schema object
        eConnect.? = myMaster;

        return MemoryStreamSerializer(eConnect);
    }

更新:

抱歉,这可能只是一个架构问题,但大约有 166 种可能的组合,为每个组合编写一个步骤似乎很荒谬。不过我可能不得不这样做......

对 eConnect 的 MS Doc 参考:http://msdn.microsoft.com/en-us/library/ff623781.aspx

调用序列化的示例代码:

    IVItemMasterType o = new IVItemMasterType();

    o.eConnectProcessInfo = null;
    o.taCreateInternetAddresses_Items = null;
    o.taCreateItemVendors_Items = null;
    o.taCreateKitItemRcd_Items = null;
    o.taItemSite_Items = null;
    o.taIVCreateItemPriceListHeader = null;
    o.taIVCreateItemPriceListLine_Items = null;
    o.taRequesterTrxDisabler_Items = null;
    o.taUpdateCreateItemCurrencyRcd_Items = null;
    o.taUpdateCreateItemRcd = eConnectHelper.taUpdateCreateItemRcdFactory(eItem);

    // Serialize into string & add to list
    List<string> sList = new List<string>();             
    sList.Add(eConnectHelper.Serialize(o));

    // Submit list to eConnect
    eCreateEntity(sList);

SerializeMemoryStream 代码:​​

    public static string MemoryStreamSerializer(eConnectType e)
    {
        XmlSerializer serializer = new XmlSerializer(e.GetType());

        using (var memoryStream = new MemoryStream())
        {
            serializer.Serialize(memoryStream, e);
            memoryStream.Position = 0;

            // Use memory streamed XML document to create a string representation of the object
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(memoryStream);
            memoryStream.Close();
            string sDocument = xmldoc.OuterXml;

            return sDocument;
        }
    }

更新 2:

非常感谢你们两位。在上面睡觉之后,我意识到我的架构中的错误。无论哪种方式我都必须构建 eConnect 对象,并且我已经在之前的方法调用中构建了子类型对象,所以我已经回溯并将类型化的序列化代码移动到主调用方法中。

我确实尝试了反射,虽然它确实编译并运行了,但由于某种原因,它除了 ObjectReference/NullReference,尽管据我所知,所有对象都被填充。

我是这样使用它的:

    public static string Serialize<T>(T o)
    {
        eConnectType e = new eConnectType();

        T[] myMaster = { o };

        // Populate the eConnectType object with the schema object
        typeof(eConnectType).GetProperty(typeof(T).Name).SetValue(e, myMaster, null);

        return MemoryStreamSerializer(e);
    }

【问题讨论】:

    标签: c# generics serialization dynamics-gp


    【解决方案1】:

    经过仔细调试后,此“getProperties”一直返回“null”引用,因为此 eConnecType 类中的成员是“字段”而不是属性...这是修复...

    public static string Serialize<T>(T o)
        {
            eConnectType e = new eConnectType();
            T[] myMaster = { o };
    
            // Populate the eConnectType object with the schema object 
            typeof(eConnectType).GetField(typeof(T).Name).SetValue(e, myMaster);
            return MemoryStreamSerializer(e);
        }
    

    【讨论】:

    • 这成功了,非常感谢!抱歉,我花了这么长时间来验证它......
    【解决方案2】:

    如果您确实需要访问与泛型类型同名的属性,则必须像这样使用反射

    typeof(eConnectType).GetProperty(typeof(T).Name).SetValue(eConnect, myMaster, null);
    

    【讨论】:

    • 您带我走上正确的道路,非常感谢,但尼克在下面给了我最终答案,我觉得有必要将他的答案设置为将来遇到此问题的人的答案。
    【解决方案3】:

    这里的问题是泛型类型参数不能控制属性名。就泛型类型系统而言,eConnect 有一个名为 IViewMasterType 的属性完全是巧合。

    您可以拥有 eConnectType&lt;T&gt; 和属性 public T[] SomePropertyName { get; set; }。换句话说,类型化的属性名称不能与其类型相关。然后你会这样做:

    public static string Serialize<T>(T o)
    { 
        eConnectType<T> eConnect = new eConnectType<T>(); 
    
        T[] myMaster = { o }; 
    
        // Populate the eConnectType object with the schema object 
        eConnect.SomePropertyName = myMaster; 
    
        return MemoryStreamSerializer(eConnect); 
    } 
    

    但是如果没有看到更多代码,很难判断这是否会有所帮助。

    编辑

    鉴于您的更新,我倾向于 Francis 使用反射的建议。反射速度较慢,但​​根据我的经验,它从未如此缓慢,以至于我实际上需要优化。

    【讨论】:

      猜你喜欢
      • 2016-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-16
      相关资源
      最近更新 更多