Возникла необходимость выполнять арифметические операции для объектов с разными типами.
Загвоздка в том, что программе эти переменные видны как object, хотя и известен их тип (класс Type).
Подскажите, как можно такое провернуть.
Далее идет код, который должен немного пояснить задачу.
/// <summary>
/// Идентификаторы типов
/// </summary>public enum DTIdentifier
{
Int,
Float,
Text,
}
public struct DTInfo
{
public string Name;
public DTIdentifier DataTypeId;
public int Length;
public Type DotNetType;
public DTInfo(string name, DTIdentifier dtid, int length, Type dotnetType)
{
Name = name;
DataTypeId = dtid;
Length = length;
DotNetType = dotnetType;
}
}
class DataType
{
public DTInfo TypeInfo { get; private set; }
private static readonly DTInfo[] AllTypes = new DTInfo[] {
new DTInfo("int", DTIdentifier.Int, 4, typeof(int)),
new DTInfo("float", DTIdentifier.Float, 8, typeof(double)),
new DTInfo("text", DTIdentifier.Text, 1000, typeof(string)),
};
// Введено для упрощения кода в данном примере.public static readonly DataType _TypeInt = new DataType(AllTypes[0]);
public static readonly DataType _TypeFloat = new DataType(AllTypes[1]);
public static readonly DataType _TypeString = new DataType(AllTypes[2]);
public DataType(DTInfo info)
{
TypeInfo = info;
}
}
class DataValue
{
public DataType DataType { get; private set; }
public int ActualLength { get; private set; }
private object m_value;
public object Value
{
get { return m_value; }
set
{
// Проверим соответствие типов и если необходимо, то выполним преобразованиеif (DataType.TypeInfo.DotNetType != value.GetType())
value = Convert.ChangeType(value, DataType.TypeInfo.DotNetType);
// Выполним дополнительные проверки, связанные с параметрами данныхswitch (DataType.TypeInfo.DataTypeId)
{
case DTIdentifier.Text:
// Для строковых данных проверим размер строки
PropertyInfo pinfo = DataType.TypeInfo.DotNetType.GetProperty("Length");
int len = (int)pinfo.GetValue(value, null);
if (len > ActualLength)
throw new Exception("Too long");
break;
}
m_value = value;
}
}
public DataValue(DataType dataType)
{
DataType = dataType;
ActualLength = DataType.TypeInfo.Length;
}
public DataValue(DataType dataType, int length)
{
DataType = dataType;
ActualLength = length;
}
}
class Program
{
static void Main(string[] args)
{
DataValue i = new DataValue(DataType._TypeInt) { Value = 10 };
DataValue f = new DataValue(DataType._TypeFloat) { Value = 1.1 };
DataValue s = new DataValue(DataType._TypeString) { Value = "string value" };
DataValue s100 = new DataValue(DataType._TypeString, 100) { Value = "short string" };
// Требуется вот это:
//DataValue r = i + f;
}
}
Требуется написать для класса DataValue операторы арифметических действий,
чтобы добиться работоспособности выражения DataValue r = i + f;
Но при этом нет особого желания делать проверки типов вручную.
Заранее спасибо. Если вдруг я вдруг неправильным путем решаю задачу, наставьте на путь истинный, пожалуйста.
Здравствуйте, Radamsa, Вы писали:
R>Требуется написать для класса DataValue операторы арифметических действий, R>чтобы добиться работоспособности выражения DataValue r = i + f; R>Но при этом нет особого желания делать проверки типов вручную.
R>Заранее спасибо. Если вдруг я вдруг неправильным путем решаю задачу, наставьте на путь истинный, пожалуйста.
Здравствуйте, Radamsa, Вы писали:
R>Доброе время суток.
R>Возникла необходимость выполнять арифметические операции для объектов с разными типами. R>Загвоздка в том, что программе эти переменные видны как object, хотя и известен их тип (класс Type). R>Подскажите, как можно такое провернуть.
Перегрузите арифметические операции в классе DataValue. Для конвертации из object при извесном Type поможет: класс Convert метод Convert.ChangeType
Перегрузка арифметических операций выглядит следующим образом:
public static DataValue operator+(DataValue left, DataValue right)
Здравствуйте, Lloyd, Вы писали:
R>>Требуется написать для класса DataValue операторы арифметических действий, R>>чтобы добиться работоспособности выражения DataValue r = i + f; R>>Но при этом нет особого желания делать проверки типов вручную.
R>>Заранее спасибо. Если вдруг я вдруг неправильным путем решаю задачу, наставьте на путь истинный, пожалуйста.
L>dynamic есть возможность использовать?
Боюсь, что dynamic использовать не удастся, т.к. целевая платформа .NET 2.0
Здравствуйте, xobotik, Вы писали:
X>Перегрузите арифметические операции в классе DataValue. Для конвертации из object при извесном Type поможет: X>класс Convert метод Convert.ChangeType X>Перегрузка арифметических операций выглядит следующим образом: X>
Здравствуйте, Radamsa, Вы писали:
R>Здравствуйте, xobotik, Вы писали:
X>>Перегрузите арифметические операции в классе DataValue. Для конвертации из object при извесном Type поможет: X>>класс Convert метод Convert.ChangeType X>>Перегрузка арифметических операций выглядит следующим образом: X>>
X>>Мануал про перегрузку операторов.
X>>P.S. Без проверки какой тип в себе держит на данный момент DataValue не обойтись.
R>Именно перегрузкой планировал реализовать, только вот проверки хотелось бы с себя скинуть и переложить на .net
Здравствуйте, xobotik, Вы писали:
X>>>Перегрузите арифметические операции в классе DataValue. Для конвертации из object при извесном Type поможет: X>>>класс Convert метод Convert.ChangeType
Кстати, класс Convert метод Convert.ChangeType на выходе даст также object, а это ничего не изменит, т.к. у меня в m_value и так лежит объект нужного типа, только вот применить к нему арифметические операции не позволено.
Ситуацию действительно может спасти dynamic (как было сказано в треде выше), но использовать его в .NET 2.0 не получается
Здравствуйте, Radamsa, Вы писали:
R>Здравствуйте, xobotik, Вы писали:
X>>>>Перегрузите арифметические операции в классе DataValue. Для конвертации из object при извесном Type поможет: X>>>>класс Convert метод Convert.ChangeType R>Кстати, класс Convert метод Convert.ChangeType на выходе даст также object, а это ничего не изменит, т.к. у меня в m_value и так лежит объект нужного типа, только вот применить к нему арифметические операции не позволено.
Надо еще привести, допустим так (int)
R>Ситуацию действительно может спасти dynamic (как было сказано в треде выше), но использовать его в .NET 2.0 не получается
Здравствуйте, Radamsa, Вы писали:
R>Доброе время суток.
R>Возникла необходимость выполнять арифметические операции для объектов с разными типами. R>Загвоздка в том, что программе эти переменные видны как object, хотя и известен их тип (класс Type). R>Подскажите, как можно такое провернуть.
Чего я не понимаю — зачем здесь наворачивается самодельная система метаданных и какие-то самопальные динамические объекты? Зачем вам свой енам для идентификации типов? System.Type и System.TypeCode не годятся? А просто object для динамических значений чем не подходит?
Отвечаю на все предыдущие вопросы о том, зачем это нужно.
В данном случае разрабатывается что-то типа своей СУБД, поэтому пришлось изобрести свои типы данных.
Если есть другой вариант реализации, о котором я не додумался, подскажите пожалуйста.
Здравствуйте, Radamsa, Вы писали:
R>В данном случае разрабатывается что-то типа своей СУБД, поэтому пришлось изобрести свои типы данных. R>Если есть другой вариант реализации, о котором я не додумался, подскажите пожалуйста.
В таком случае вы только начали изучать грабельное поле — по самым скромным оценкам вам предстоит ещё пара человеколет удивительных открытий
Своя СУБД, да ещё и под .Net 2.0 — неужели диплом?
Здравствуйте, Sinix, Вы писали:
S>Своя СУБД, да ещё и под .Net 2.0 — неужели диплом?
Кстати, я сейчас играюсь с чем-то подобным — на клиентской стороне хочется максимально производительную, расширяемую in-memory column-based .net native db with relaxed ACID properties — что-то наподобие DataSet, даже не нужна поддержка SQL. К сожалению, не нашел ничего, удовлетворяющего всем нашим требованиям.
Здравствуйте, Radamsa, Вы писали:
R>Возникла необходимость выполнять арифметические операции для объектов с разными типами. R>Загвоздка в том, что программе эти переменные видны как object, хотя и известен их тип (класс Type).
Можно применить подход, описанный в Generics Algorithms с тем лишь изменением, что тип будет задаваться не статически ("new AlgorithmLibrary<double>"), а с помощью фабрики на основании рантайм-информации о реальном типе вашего object-а.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Andy77, Вы писали:
A>Кстати, я сейчас играюсь с чем-то подобным — на клиентской стороне хочется максимально производительную, расширяемую in-memory column-based .net native db with relaxed ACID properties — что-то наподобие DataSet, даже не нужна поддержка SQL. К сожалению, не нашел ничего, удовлетворяющего всем нашим требованиям.
Вы не поверите — аналогичный велосипед
Только не DBMS ни разу, просто правильно реализованный DataSet.
Здравствуйте, _FRED_, Вы писали:
_FR>Можно применить подход, описанный в Generics Algorithms.
Насколько я понял, топикстартер хочет ещё и скрещивать ежа с ужом — складывать строки и числа. Я пока не могу придумать ничего достаточно быстрого, кроме кэшированного ExpressionTree — отпадает, т.к. топикстартер ограничил себя 2м фреймворком.
A>Кстати, я сейчас играюсь с чем-то подобным — на клиентской стороне хочется максимально производительную, расширяемую in-memory column-based .net native db with relaxed ACID properties — что-то наподобие DataSet, даже не нужна поддержка SQL. К сожалению, не нашел ничего, удовлетворяющего всем нашим требованиям.