泛型方法、泛型类型、泛型参数

发布于 2024-12-15 17:19:00 字数 3174 浏览 2 评论 0原文

我什至不知道如何描述我正在尝试做的事情(对不起,新手),但是因为我还没有弄清楚如何正确执行而重复代码在我的列表中并不重要。有什么帮助吗?

原始的非泛型方法:

    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 种可能的组合和为每个步骤编写这一步似乎很荒谬。不过,我可能必须这样做...

MS Doc 对 eConnect 的引用: 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);
    }

I'm not even sure how to describe what I'm trying to do (sorry, newb), but duplicating code because I haven't figured out how to do correctly isn't high on my list. Any help, please?

Original non-generic method:

    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);
    }

My attempt at generic, so close, lost at setting typed property (?):

    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);
    }

Update:

Sorry, this all may just be an architecture thing, but there's around 166 possible combinations and it just seems ridiculous to code this one step for each one. I may have to do just that though...

MS Doc reference to eConnect: http://msdn.microsoft.com/en-us/library/ff623781.aspx

Example code that calls the serialization:

    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 code:

    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;
        }
    }

Update 2:

Many thanks to both of you. After sleeping on it, I realized the error in my architecture. I have to build the eConnect object either way and I'm already building the sub-type object in the previous method call, so I've back-tracked and moved the typed serialize code into the main calling method.

I did try the reflection, and while it did compile and run, for some reason it excepted with an ObjectReference/NullReference despite, as far as I could tell, all the objects being populated.

Here's how I was using it:

    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);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

对你再特殊 2024-12-22 17:19:00

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

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

If you really need to access a property with the same name of your generic type, you would have to use Reflection as so

typeof(eConnectType).GetProperty(typeof(T).Name).SetValue(eConnect, myMaster, null);
诗笺 2024-12-22 17:19:00

这里的问题是泛型类型参数无法控制属性名称。就通用类型系统而言,eConnect 有一个名为 IViewMasterType 的属性这一事实完全是巧合。

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

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); 
} 

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

编辑

根据您的更新,我倾向于弗朗西斯使用反射的建议。反射速度较慢,但​​根据我的经验,它从未慢到我真正需要优化的程度。

The problem here is that the generic type parameter can't control the property name. The fact that eConnect has a property called IViewMasterType is entirely coincidental as far as the generic type system is concerned.

You could have eConnectType<T> with a property public T[] SomePropertyName { get; set; }. In other words, the typed property name can't be related to its type. Then you'd do this:

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); 
} 

But without seeing more of your code it's hard to tell whether this would help.

EDIT

In light of your update, I would lean towards Francis's suggestion of using reflection. Reflection is slower, but in my experience it has never been so slow that I actually needed to optimize.

jJeQQOZ5 2024-12-22 17:19:00

经过一番仔细调试后,此“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);
    }

After some careful debugging this "getProperties" kept returning "null" references because the members in this eConnecType Class are "Fields" not properties... Here is the fix...

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);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文