Общий метод, Общий тип, Общий параметр - PullRequest
0 голосов
/ 15 ноября 2011

Я даже не уверен, как описать то, что я пытаюсь сделать (извините, новичок), но дублирование кода, потому что я не понял, как это сделать правильно, не входит в мой список. Любая помощь, пожалуйста?

Оригинальный неуниверсальный метод:

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

Ответы [ 3 ]

1 голос
/ 16 ноября 2011

Если вам действительно нужно получить доступ к свойству с тем же именем, что и у вашего универсального типа, вам придется использовать Reflection, так что

typeof(eConnectType).GetProperty(typeof(T).Name).SetValue(eConnect, myMaster, null);
1 голос
/ 22 февраля 2012

После некоторой тщательной отладки этот getProperties продолжал возвращать пустые ссылки, потому что члены этого класса 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);
    }
1 голос
/ 15 ноября 2011

Проблема в том, что параметр универсального типа не может управлять именем свойства.Тот факт, что eConnect имеет свойство, называемое IViewMasterType, полностью совпадает с системой родовых типов.

Вы можете иметь eConnectType<T> со свойством 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); 
} 

Но, не видя больше вашего кода, трудно сказать, поможет ли это.

РЕДАКТИРОВАТЬ

В свете вашего обновленияЯ склонялся бы к предложению Фрэнсиса использовать отражение.Отражение медленнее, но, по моему опыту, оно никогда не было таким медленным, что мне действительно нужно было оптимизировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...