3

I have a list of parameters to read, and need to get their max value. I am not talking about a List but about several int values :

int ColAssComm = Register.getImportExcelDSTV("AssComm")-1;
int ColAssDwg = Register.getImportExcelDSTV("AssDwg") - 1;
int ColAssGpe = Register.getImportExcelDSTV("AssGp") - 1;
int ColAssName = Register.getImportExcelDSTV("AssName") - 1;
int ColAssPrio = Register.getImportExcelDSTV("AssPrio") - 1;
int ColAssPds = Register.getImportExcelDSTV("AssPds") - 1;
int ColAssSurfPaint = Register.getImportExcelDSTV("AssSurfPaint") - 1;
int ColAssQty = Register.getImportExcelDSTV("AssQty") - 1;
int ColRepName = Register.getImportExcelDSTV("RepName") - 1;
int ColRepQty = Register.getImportExcelDSTV("RepQty") - 1;
int ColRepExecutionClass = Register.getImportExcelDSTV("RepExecutionClass") - 1;
int ColRepTreatment = Register.getImportExcelDSTV("RepTreatment");

And I need to do somthing like

int maxvalue = Max(ColAssComm,ColAssDwg..., ColRepTreatment)

Is there a way to do it all at once?

Siegfried.V
  • 1,508
  • 1
  • 16
  • 34
  • No, as I know. But if they are class members, you can perhaps use reflexion, if there is no other var for example, or using prefix `col` here to filter. Can you give more details, please? –  Dec 04 '20 at 17:50
  • 2
    Put them all in an array and call `Max` on that? `int maxValue = (new[] { item1, item2, ...}).Max();` –  Dec 04 '20 at 17:52
  • @Knoop thanks, great idea, simple, even if I didn't think about it myself. Maybe you can write it as answer so I could accept it? – Siegfried.V Dec 04 '20 at 17:53
  • @Knoop OP asks if it is possible to do that "*all at once*", meaning without listing the vars as I understand. –  Dec 04 '20 at 17:55
  • @OlivierRogier well that's what I wanted, not to write 10-20 times the "max", so that answer fits me very well, as I see nothing better. Regarding your comment excuse me, but I didn't understand what you meant as I don't know what is reflexion. there is no more details to give I think, I read some parameters.In that case, the function reads in registers in which columns of Excel file I can find necessary information. (the "-1" is in the case I read a csv file) – Siegfried.V Dec 04 '20 at 17:59
  • @RyanWilson would be great, thanks. I don't what are generics, always interesting to learn something new, thanks – Siegfried.V Dec 04 '20 at 18:05
  • @SiegfriedV If variables are declared at the class level, that said they are fields members, you can use a short reflexion loop with a filter on names to get a list to apply Max method on it without listing all the vars by hand. But if they are local vars, you cannot : stackframe does not have locals names but you can get debug info symbols (I don't know how to do that). What do you have and do you want reflexion? –  Dec 04 '20 at 18:10
  • 1
    Another option would be to NOT use separate variables in the first place. Instead, use a `Dictionary` to hold those values. Then you could look them up using the same string that you used to retrieve them from `getImportExcelDSTV()`. You'd also be able to query it using LINQ to get the max value back with the key name as well. – Idle_Mind Dec 04 '20 at 18:10
  • @Idle_Mind thanks, again an interesting comment... is it possible to use dictionary, and save dictionary in registers? – Siegfried.V Dec 04 '20 at 18:12
  • What do you mean by "save in registers"? – Idle_Mind Dec 04 '20 at 18:13
  • @SiegfriedV In fact you read some values from somewhere you call registers, and store them in vars, local it seems : you can have an array of params `{ "AssComm", "AssDwg"... }` and read values in a dictionary having params as key, without using vars. Isn't that? In this case you will have a simple way to apply anything you need on the collection, like `Max`. –  Dec 04 '20 at 18:14
  • @Idle_Mind let's say I made an application (already big). And I have 2 kind of parameters : Parameters common to all users (that I save in database), then parameters that may be different for each user. In that case this is for importing a nomenclature in Excel or csv file. Depending on who makes the list, the columns can be different, that's why I made a "config" window, where user can set its favourite configuration. Then I want to read the max value, in order that when I load Excel, I say how many columns I need to read. – Siegfried.V Dec 04 '20 at 18:18
  • @OlivierRogier excuse me, maybe "regiser" is not good translate, but registry? (what I open with regedit, what's the name?) – Siegfried.V Dec 04 '20 at 18:19
  • I'm sure it could be done, but using the Registry for dynamic data like this isn't really a good idea. Instead, I'd probably write a custom CLASS to encapsulate this information with possibly some `List<>`s or `Dictionary<>`s within, then either use XML or JSON to serialize to a file. – Idle_Mind Dec 04 '20 at 18:23
  • @Idle_Mind well in fact I could have used XML file, but I was sure (but seems I was wrong?) that it was better to have all in registry, than using files. I will create new question regarding that, cause I think it is also important. – Siegfried.V Dec 04 '20 at 18:25
  • @Idle_Mind what is advantage using an xml file , instead of registry? in fact I like the idea of using dictionary, but I prefer using registry than having a file, is there a reason why registry is bad? (opened a question regarding that) – Siegfried.V Dec 04 '20 at 18:49

2 Answers2

4

Another option would be to create a generic method like the following:

public T FindMax<T>(params T[] items)
{
    return items.Max();
}

Then you can pass a dynamic amount of parameters into the method, so you could just pass all your variables from your example into this method and get back the MAX of whatever type you wanted, this could work for integers and doubles and decimals... etc.

Ryan Wilson
  • 10,223
  • 2
  • 21
  • 40
  • 1
    This is the way – Wyck Dec 04 '20 at 18:06
  • @RyanWilson wait wait wait... are U telling me that I can make that kind of function using also objects? I mean, if I want to make a function AddQuantities() for example, I can pass any object inside, and write `return items.Sum(x=>x.Qty` (supposing all objects will have a field "Qty"... if so you just made my day, as it is months I was looking for such a solution... – Siegfried.V Dec 04 '20 at 18:09
  • @Siegfried.V Yes. You could potentially pass in `objects` to your proposed method `AddQuantitites` and use `Linq` to `Sum` their property of `.Qty`. `Generics` are a very great tool to have in the bag. I suggest learning more about them. – Ryan Wilson Dec 04 '20 at 18:12
  • @RyanWilson you got all my atention, of course I'll learn about them, I already will use them with the function I need now, then will try to use them replacing some old functions. Thanks for the great help :) – Siegfried.V Dec 04 '20 at 18:14
  • @Siegfried.V You're welcome. I'm glad I could help. Happy coding! – Ryan Wilson Dec 04 '20 at 18:14
1

As suggested by @Idle_Mind you can use a dictionary like that:

using System.Collection.Generic;

string[] ParamNames =
{
  "AssComm", "AssDwg", "AssGp", "AssName", "AssPrio", "AssPds",
  "AssSurfPaint", "AssQty", "RepName", "RepQty", "RepExecutionClass", "RepTreatment"
};

Dictionary<string, int> ParamsData = new Dictionary<string, int>();

Thus we define once an array having a list of parameter's names needed.

Next we define a dictionary having param's names as key without using multiple vars.

Next we initialize the dictionary from the stored values.

foreach ( string paramName in ParamNames )
  ParamsData.Add(paramName, Register.getImportExcelDSTV(paramName) - 1);

Therefore we have a simple way to apply anything we need on the collection like Max.

using System.Linq;

int max = ParamsData.Values.Max();

Also we can access params using:

ParamsData["AssComm"] = 10;

We can of course define string variables to not write by string these names:

string ColAssCommName = "AssComm";
string ColAssDwgName = "AssDwg";
...

Doing that we write:

string[] ParamNames = { ColAssCommName, ColAssDwgName ...}

And:

ParamsData[ColAssCommName] = 10;

To save we write something like that:

foreach ( string paramName in ParamNames )
  Register.setImportExcelDSTV(paramName, ParamsData[paramName] + 1);
  • thanks for that example, today will have lerned many useful things. May I ask you to have a look on my question about preferences to use registry or xml files? https://stackoverflow.com/questions/65148873/best-way-for-saving-local-parameters – Siegfried.V Dec 04 '20 at 18:34
  • It depends on the use: applications preferences like forms location, font sizes and so on, they should be stored using the application settings system (registry is obsolete for that and .NET offers advanced and generally automatic management). For others things choosing Registry, INI, XML, JSON, serialization, binary, plain text... is about opinion and the project... –  Dec 04 '20 at 18:40
  • just if I understood correctly, there is a mistake on that line `foreach ( string paramName in ParamNames ) ParamsData.Add(paramName, Register.getImportExcelDSTV("AssComm") - 1);`, it may be `foreach ( string paramName in ParamNames ) ParamsData.Add(paramName, Register.getImportExcelDSTV(paramName) - 1);`, right? – Siegfried.V Dec 04 '20 at 18:40
  • Thanks to you :) – Siegfried.V Dec 04 '20 at 18:43
  • About application settings: [Using Application Settings and User Settings](https://learn.microsoft.com/dotnet/desktop/winforms/advanced/using-application-settings-and-user-settings) & [C# application settings tutirial](https://www.google.com/search?q=c%23+application+settings+tutorial) and also [How to change the location of the Application.exe.config file in .net](https://stackoverflow.com/questions/58219475/how-to-change-the-location-of-the-application-exe-config-file-in-net/58220768#58220768) –  Dec 04 '20 at 18:45
  • 1
    I already used this 2-3 years ago (at beginning of the project), but I don't remember why this didn't fit to my needs ( I also remember that sometimes it was reseted and needed to redefine them), and as I have hundreds of settings, I just stopped to use it – Siegfried.V Dec 04 '20 at 18:46
  • Indeed, app settings is not for data. Thus you may use a file in user "UserDirectory\AppData\Roaming\OrganizationName\ApplicationName(\Settings)\", not registry, with any file format you need, want or like. SQLite also, or anything else. –  Dec 04 '20 at 18:48
  • I am not against changing my way of coding at all... but I have already hundreds of parameters set (4 years I go adding them). So why would be a good reason to use a file, instead of registers? Why registry is a bad option? – Siegfried.V Dec 04 '20 at 18:51
  • Indeed, about what you said, keep that, don't change, otherwise you have a good reason which may be portability and maintainability as well as better and typed data storage and manipulation, so a better OOP design and a better clean code. –  Dec 04 '20 at 18:58
  • About portability I don't need, as I set default values for all settings, users are free to change them regarding their preferencies. Then for maintenance, most of time if there is something, I remotely solve problems (it helps keep contact with customers), and these parameters are not "critical", these are parameters as order displaying columns and so on, all important parameters are on database, and only administrator can edit them. – Siegfried.V Dec 04 '20 at 19:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/225541/discussion-between-siegfried-v-and-olivier-rogier). – Siegfried.V Dec 04 '20 at 19:06