Какую версию выбрать?
EnergyTotalКакую версию выбрать?
internal static string HomeCurrency = null;
public const string TotalHomeCurrency = "total"; //+ homeCurrency;
public const string EnergyTotalHomeCurrency = "energyTotal"; //+ homeCurrency
public static String Total
{
get {
if (HomeCurrency == null) { throw new Exception("HomeCurrency need to be specified priof access Total"); }
return TotalHomeCurrency + " " + HomeCurrency;
}
}
public static String EnergyTotal(string pHomeCurrency) { return EnergyTotalHomeCurrency + " " + pHomeCurrency; }
Это - динамические имена полей.
Почему надо добавлять валюту - не знаю и не интересно
Во второй версии (EnergyTotal) - валюту надо таскать с собой в параметрах, а в первой - нарушается ООП...
Могу добавить инициализацию на первом вызове... но как-то криво получается...
Какую версию выбрать?
Просто статический класс обслуживающий имена полей.
Обычно в нем лежат простые константы, но в данном случае имена строятся динамически - константа + "валюта".
Понятно, что либо статический метод, либо статическая проперть.
При методе надо таскать "валюту" параметром, при проперти - надо принудить задавать до первого использования.
Но Я вроде нашел вариант - запихал получение "валюты" в статический конструктор... и помятуя об проблемах со статическим переменными в классах лежащих в либах - еще и засинглетонил... работает...
Завтра буду смотреть можно ли исключить "валюту" в других местах куда ее пасовали...
Ну у тебя и кодинг стиль. В последний раз венгерская нотация я помню была в плюсах. Долго старался понять какого там поинтер у тебя делает?
Похоже на очередной костыль к тому, что имеется. Что то типа вопроса вам гильотину каким маслом смазать?
Ты же вроде правильно стараешься делать. Какого имена полей вообще в "ручном" коде делают? Было вроде это в какие-то далекие времена, но уже забыл.
Долго старался понять какого там поинтер у тебя делает?
-----
Ну это бывает... с Шарпе поинтеров нема, но есть параметры. А без "п" - мне уже неудобно...
Похоже на очередной костыль к тому, что имеется.
-----
Ну да - очередной кусок конвертится в объектную форму.
Требуются - имена полей в табличке... ну и вместо того чтобы разбираться во всех 100500 местах где их собирают с тем правильно ли их собирают - все скинуто в субкласс и изолировано от внешнего кода...
Оставалось выбрать в какой форме писать... бо, обычно, там константы и никакие манипуляции не требуется...
Ну а тут - динамика - надо базировать на строках из другой таблицы...
И либо таскать строку, либо придумать ка без этого обойтись...
Придумал... повторов суффиксов нигде нет и работает нормально...
Код, кстати, подсократился и стал более-менее понятным...
Какого имена полей вообще в "ручном" коде делают?
-----
Оригинальная часть:
Private Function fillDRResultCommodities(ByVal DTItemsByCustomer As DataTable, _ByVal DTDistinctIntrastatCodes As DataTable, _
ByVal DRResult As DataRow) As DataRow
Dim sqlFilter As String = Nothing
Dim DRFilter() As DataRow = Nothing
Dim intrastatCode As String = Nothing
Dim columnHeader As String = Nothing
Dim netPriceHomeCurrency As Decimal = 0
Try
For Each DRDistinctIntrastatCode As DataRow In DTDistinctIntrastatCodes.Rows
intrastatCode = DRDistinctIntrastatCode.Item("intrastatCode").ToString & " "
columnHeader = intrastatCode & _
DRDistinctIntrastatCode.Item("commodity").ToString
sqlFilter = "intrastatCode=" & DRDistinctIntrastatCode.Item("intrastatCode").ToString
DRFilter = DTItemsByCustomer.Select(sqlFilter)
If DRFilter.Length > 0 Then
netPriceHomeCurrency = DTItemsByCustomer.Compute("SUM([netPrice homeCurrency])", sqlFilter)
DRResult.Item(columnHeader) = netPriceHomeCurrency.ToString
columnHeader = intrastatCode & "statVal"
' DRResult.Item(columnHeader) = netPriceHomeCurrency - (netPriceHomeCurrency / 100)
DRResult.Item(columnHeader) = netPriceHomeCurrency
columnHeader = intrastatCode & "weight"
DRResult.Item(columnHeader) = DTItemsByCustomer.Compute("SUM(weight)", sqlFilter)
columnHeader = intrastatCode & "sqm"
DRResult.Item(columnHeader) = DTItemsByCustomer.Compute("SUM(sqm)", sqlFilter)
End If
Next
Catch ex As Exception
End Try
Return DRResult
End Function
переработанный код:
public void FillCommodities(TDistinctIntrastatCodes.Distinct pDistinctIntrastatCodes, TItems.Subset pItemsbyCustomer){try {foreach (TDistinctIntrastatCodes.Row intrastatCodeRow in pDistinctIntrastatCodes){Filters.ByIntrastatCode byIntrastatCode = new Filters.ByIntrastatCode();byIntrastatCode.IntrastatCode = intrastatCodeRow.IntrastatCode;TItems.Subset itemsByIntrastatCode = pItemsbyCustomer.Select(byIntrastatCode);if (itemsByIntrastatCode.HasData){TIntrastatCodeRowProxy icp = this[intrastatCodeRow];string netPriceHomeCurrency = itemsByIntrastatCode.SumNetPriceHomeCurrency.ToString();icp.IntrastatCodeComodity = netPriceHomeCurrency;icp.StatVal = netPriceHomeCurrency;icp.Weight = itemsByIntrastatCode.SumWeight.ToString();icp.Sqm = itemsByIntrastatCode.SumSqm.ToString();}}} catch (Exception ex){TExceptionHandler.Error(ex);}}
Упростилось до уровня понимабельности... имена полей - ушли... об ошибочке - письмишко придет... ну и тестируемость доступна...
Вроде нормально?
У меня правда, толерантность весь низкая к подобному коду -.SumWeight.ToString();
-----
У меня - тоже.
Но Шарп не делает конвертацию децималов в строки, а проперти в оригинале разнотипные.
Можно или нельзя привести их к одному типу - надо смотреть...
А пока у нас тут одна из писишек подыхая начала ложить все сетку...
Какая - непонятно - никто не жалуется на невозможность, все жалуются на медленно...
Вот надо найти и выключить... или заменить... в зависимости от того где...
Да, кстати - есть какое решение для проперти, которой можно присвоить значения двух разных типов?
В данном случае - стринг и децимал, но интересует обобщенное - ТСтринг и ТДецималВизKолор...
есть какое решение для проперти, которой можно присвоить значения двух разных типов?
Ты вообще код хочешь улучшить или ухудшить?
Модель имеет десимал, а уж при отображении делаешь два конвертора. В WPF это почти встроено, в MVC можно почти также сделать.
У тебя небось еще Веб-формс
Делай тогда три проперти, две из которых реадонли.
Делай тогда три проперти, две из которых реадонли.
-----
Разноименные? Нее, так не интересно...
Интерсно - чтобы имя оставалось, а присваивать можно было только оговоренные типы и конвертирование контролировалось...
Делал когда-то давно... через прокси-тип... но уже все позабыл...
Ты наверное это просто по другому называешь
public static T Total { get { return abc; } }
ломит все писать, сорри
https://docs.microsoft.com/en-us/dotnet/csharp/programming...
Неее :) Насколько я понял, ему нужно вот что:
public class MyClass { public void SetValue (decimal val) { Value = val.ToString(); } public void SetValue(string val) { Value = val; } public string Value { get; private set; } }
Вадиант с генериком дает возможность выбрать тип проперти, то тип все равно один.
Мне интересно следующее:
public class Type1 { }public class Type2 { }public class Type3 { }public class TypedPropertyHolder{public object Value { get; set; } // define restriction to use Type1 and Type2 only
}public class WorkingCode{WorkingCode() {TypedPropertyHolder tph = null;tph.Value = new Type1(); // Oktph.Value = new Type2(); // Oktph.Value = new Type3(); // Error at compilation time}}
На нулл, естественно не смотрим, а делаем только работу на ограничения по типам.
Ну и естественно не интересует вариант с общим базовым классом...
Нее, не то.
Грубо будет так:
У меня в базе есть с десяток генераторов последовательностей.
Обычно - генерируется значение, которое используется как первичный и вторичный ключи.
Сейчас это обычное целое и может быть присвоено в любое целочисленное поле.
Меня же интересует чтобы были описаны ограничения и Я мог присвоить значение ключа:
- только во вторичные ключи
и
- только в соответствии с реляциями.
Как я и сказал :)
public class Type1 { } public class Type2 { } public class Type3 { } public class TypedPropertyHolder { public void SetValue (Type1 val) { Value = val; } public void SetValue (Type2 val) { Value = val; } public object Value { get; private set; } // define restriction to use Type1 and Type2 only } public class WorkingCode { WorkingCode() { TypedPropertyHolder tph = null; tph.SetValue(new Type1()); // Ok tph.SetValue(new Type2()); // Ok tph.SetValue(new Type3()); // Error at compilation time } }
Как я и сказал :)
-----
Увы...
Но меня не интересует написание и использование методов под каждый тип - меня интересует проперть-с-ограничением по типам...
public class Type1 { }
public class Type2 { }
public class Type3 { }
public class WorkingCode
{
WorkingCode() {
TypedPropertyHolder tph = null;
tph.Value = new Type1(); // Ok
tph.Value = new Type2(); // Ok
tph.Value = new Type3(); // Error at compilation time
}
}
public class TypedPropertyHolder
{
internal TypeProxy Value { get; set; } // define restriction to use Type1 and Type2 only
}
internal class TypeProxy
{
object t;
internal TypeProxy(object pT) { t = pT; }
public static implicit operator TypeProxy(Type1 t1) { return new TypeProxy(t1); }
public static implicit operator TypeProxy(Type2 t2) { return new TypeProxy(t2); }
public static implicit operator Type1(TypeProxy p) { return (Type1)p.t; }
public static implicit operator Type2(TypeProxy p) { return (Type2)p.t; }
}
Вроде вспомнил как делал...