Неявное преобразование между типами в C # - PullRequest
3 голосов
/ 18 августа 2011

У меня есть следующие бизнес-объекты:

    public abstract class Product
    {
        public int Id { get; set; }
        public bool OnStock { get; set; }
    }

    public class ProductForImport : Product
    {
        public int ImportId { get; set; }
    }

    public class ProductForExport : Product
    {
        public int ExportId { get; set; }
        public bool IsExportable { get; set; }
        public bool IsUsable { get; set; }
        public string OtherParam {get; set;}

        public static implicit operator ProductForExport(ProductForImport pfi)
        {
            ProductForExport p = new ProductForExport();
            p.Id = pfi.Id;
            p.IsExportable = true;
            p.ExportId = 0;
            return p;
        }
    }

, чтобы я мог конвертировать между двумя типами:

    static void Main(string[] args)
    {
        ProductForExport pfe = new ProductForExport();
        pfe.Id = 1;
        pfe.OnStock = true;

        ProductForImport pfi = new ProductForImport();
        pfi.ImportId = 200;

        ProductForExport pfe2 = (ProductForExport)pfi;
    }

это работает нормально.

У меня есть 100.000 товаров для импорта товаров. Если я правильно понимаю, если я преобразую их в элементы ProductsForExport, у меня в памяти будет 100 000 + 100 000 элементов - это разумно.

Моя проблема заключается в следующем: мне нужно отправить эти объекты «ProductForExport» через сервисы JSON, каждому сервису просто нужно некоторое подмножество свойств каждого типа:

servicecall1 должен вернуть ProductForExport1{ExportId,IsExportable}

servicecall2 должен вернуть ProductForExport2{ExportId,IsUsable}

Вопрос: я должен написать неявное преобразование, подобное приведенному выше примеру, для этих новых типов - ProductForExport1 и ProductForExport2 (поэтому в основном создайте 100 000 + 100 000 новых объектов)

или

каким-то образом я могу просто "спрятать" нежелательные свойства с помощью некоторой магии от исходного типа без необходимости создавать новые экземпляры?

спасибо,

б.

Ответы [ 5 ]

3 голосов
/ 18 августа 2011

Я бы создал легкие объекты специально для возврата через сервис только с обязательными полями.Затем используйте Automapper или что-то подобное, чтобы отобразить их.

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

3 голосов
/ 18 августа 2011

Если вам нужен такой вид разделения и разделения сущностей - вы можете создать DTO объект вместе с каждым бизнес-объектом и использовать DTO для связи со Сервисом.Но если у вас есть много бизнес-объектов, рассмотрите другой подход, чтобы избежать ада обслуживания.

public sealed class ExportProductDto
{
   public(ProductForExport exportProduct)
   {
       // initialize fields
       this.ExportId = exportProduct.ExportId;
   } 

   public int ExportId { get; private set; }
}

Кстати, решение с избыточным количеством ресурсов с перегрузкой оператора, используйте Шаблон адаптера для преобразования между типами продуктов.

Чтобы отделить адаптацию от сущностей, самостоятельно реализуйте следующий интерфейс:

public interface IProductAdapter<TImport, TExport>
{
    TImport ToImportProduct(TExport exportProduct);
    TExport ToExportProduct(TImport importProduct);
}

Или другой подход адаптера:

// Implement this interface for ProductForImport class
// public class ProductForImport : IExportProductAdapter, Product
public interface IExportProductAdapter
{
    ProductForExport ToExportProduct();
}

// Implement this interface for ProductForExport class
// public class ProductForExport : IImportProductAdapter, Product
public interface IImportProductAdapter
{
    ProductForImport ToImportProduct();
}

РЕДАКТИРОВАТЬ: Ответ на комментарии

// An example of IExportProductAdapter adapter implementation
public sealed class ProductForImport : Product, IExportProductAdapter
{
     public int ImportId { get; set; }

     public ProductForExport ToExportProduct()
     {
        ProductForExport p = new ProductForExport();
        p.Id = this.Id;
        p.IsExportable = true;
        p.ExportId = 0;
        return p;
     }
}

И тогда вместо:

 ProductForExport pfe2 = (ProductForExport)pfi;

Вы можете сделать:

 ProductForExport pfe2 = pfi.ToExportProduct();
2 голосов
/ 18 августа 2011

Если вы используете WCF, вы можете применить IgnoreDataMemberAttribute к свойствам, которые вы не хотите сериализовать.

1 голос
/ 18 августа 2011

Мне потребовалось несколько чтений, но я не думаю, что ваша проблема заключается в неявном преобразовании, а в том, как отправить данные через json, верно?

Если у вас есть свои коллекции объектов из объектов импорта или экспорта, выможно использовать JavaScriptSerilizer и некоторые анонимные типы для нарезки и нарезки данных, которые вы отправляете.

Вы можете использовать Linq, чтобы выбрать конкретные свойства вашего объекта в коллекции и определить анонимный тип «на лету»сериализовать в виде строки JSON, как это:

List<ProductForExport> exportList; //the list to export
JavaScriptSerializer jss = new JavaScriptSerializer();
string output = string.Empty;

output = jss.Serialize(new
    {
        isExportable = True,                //static named properties
        iTotalProducts = exportList.Count,  //dynamic values
        productDataArray = exportList       //all data in an array object
    });

//Or build the result using just a few properties of the collection:

foreach (ExportProduct exProd in exportList)
{
    output += jss.Serialize(new
    {
        exProd.IsExportable,
        exProd.ExportID
    });
}
1 голос
/ 18 августа 2011

Взгляните на ScriptIgnoreAttribute , чтобы исключить свойства из сериализации json.

...