Каков наилучший способ представления сумм свойств для типа в классе?

У меня есть стороннее приложение, которое предоставляет объект с множеством "атрибутов", которые являются просто парами (строковыми) ключами и значениями. Типы значений могут быть либо строками, DateTime, Int32, либо Int64.

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

Ключи атрибутов будут представлены как перечисление для клиентов (чтобы скрыть информацию о конкретных ключевых строках стороннего приложения). Однако я не уверен, как представлять ценности. Вот некоторые из вариантов:

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

public class MyObject
{
    public Dictionary<MyTextAttributeKeysEnum, string> TextAttributes { get; set; }
    public Dictionary<MyDateAttributeKeysEnum, DateTime> DateAttributes { get; set; }
    public Dictionary<MyNumAttributeKeysEnum, long> NumericAttributes { get; set; }

    public string Name { get; set; }
    public string Id{ get; set; }

Вариант 2: Преобразование всех атрибутов в строки

public class MyObject
{
    public Dictionary<MyAttributeKeysEnum, string> MyAttributes { get; set; }

    public string Name { get; set; }
    public string Id{ get; set; }

Вариант 3: Храните их в виде объектов, позволяйте клиентам беспокоиться о литье и конвертировании

public class MyObject
{
    public Dictionary<MyAttributeKeysEnum, object> MyAttributes { get; set; }

    public string Name { get; set; }
    public string Id{ get; set; }

Ответ 1

Использование нескольких словарей просто не выглядит красиво:) Но может работать в некоторых сценариях.

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

Если вы хотите действительно простое прямое решение - просто пойдите с объектами. Несмотря на то, что он вводит бокс /unboxing для типов значений (забудьте об этом, если вы не используете тысячи объектов), и вы потеряете информацию о типе по значениям, это решение может по-прежнему работать нормально.

Также вы можете подумать о введении промежуточного класса для значения. Что-то вроде

public Dictionary<MyAttributeKeysEnum, PropertyBagValue> MyAttributes { get; set; }

public class PropertyBagValue
{
    public object AsObject { get; set; }
    public string AsString { get; set; }
    public int AsInt { get; set; }
    // ...
}

Внутренне вы можете сохранить свое значение в переменной исходного типа (int в переменной int, в строке в строковой переменной и т.д., т.е. иметь отдельную переменную для каждого типа), а затем вы можете избежать преобразования типов. Также вы можете обернуть словарь в другом классе, добавить несколько полезных аксессуаров и сделать его более привлекательным. Я не знаю, как это вписывается в вашу инфраструктуру.

Ответ 2

Как сделать вас абстрактным классом DataContract и предоставить словари типам, которые вам нужны в производных классах:

[DataContract]
[KnownType(typeof(My3dPartyObjectString))]
[KnownType(typeof(My3dPartyObjectInt64))]
public abstract class My3dPartyObjectBase
{
// some common properties
}

[DataContract]
public class My3dPartyObjectString : My3dPartyObjectBase
{
public Dictionary<3PAttributeKeysEnum, string> MyStringAttributes { get; set; }
}

[DataContract]
public class My3dPartyObjectInt64 : My3dPartyObjectBase
{
public Dictionary<3PAttributeKeysEnum, long> MyStringAttributes { get; set; }
}

Затем клиенту придется анализировать реальный тип возвращаемого объекта и получать набор атрибутов на основе типа. Это будет близко к вашей 3D-опции, но клиент будет по крайней мере иметь некоторую безопасность типов на уровне объекта ответа.