I have written a dll in C# which has five .cs files. ControlsOnForm.cs has a public enum defined in it.
public enum FormControls {
Button,
Label,
DataGrid,
TextBox
}
Now, I'm using this dll in a Windows app which is shown in attached Image1 and when I click Generate button it generates the ControlsOnForm.cs C# file which is same as the enum in dll.
Now how do I refer/use this dynamically generated C# file with enum values in dll.
Or in another words the enum values in ControlsOnForm.cs of dll should get replaced with the newly generated C# file's enum values.
Thanks,
Although it is trivial to get your code to generate a cs file. I suspect what you then want to do is run the resulting code. That step is highly difficult and there are many things you need to understand in terms of the limitation.
However as another user has commented, it sounds like what you want to change is data, and not code.
You should understand the distinction between hardware, firmware, code, configuration and data. The lines are much more blurred than you might first think. But at the end of the day, each is a step in a continuum of changeability. For your purpose, code should be the thing that changes the least often. This in our tool chain it is the hardest to change. Remember at the end of the day everything is ones and zeros... and your data should also change how your program works.
Enums are a collection of named constants. In the same sense that you cannot change a constant, you cannot change an enum (at least without jumping through a ton of hoops).
What you really want to do here is use an external dataset, be it a datatable, an XML configuration file, etc.
On a side note, you would probably want to create an enum outside of a form, but in the same namespace. You can add a module to a project and drop all your enums in there.
From MSDN:
The enum keyword is used to declare an enumeration, a distinct type
that consists of a set of named constants called the enumerator
list.
Usually it is best to define an enum directly within a namespace so
that all classes in the namespace can access it with equal
convenience. However, an enum can also be nested within a class or
struct.
Reference: MSDN Enum Entry
Related
I'm a bit confused about C#'s use of attributes. At first I thought it was simply used to give program code additional information through the use of the [Obsolete] attribute. Now I find that [Dllimport] can be used to import a dynamic linked library and its functions. Can attributes import .exe files and other kind of files?
A last question, for programmers working in C# every day, how much do you use attributes, and do you use it for anything else than extending information and importing dll's?
Simply said, attributes are just metadata attached to classes or methods, at the very base.
The compiler, however, reads through your code, and runs specific actions for specific attributes it encounters while doing so, hardcoded into it. E.g., when it finds a DllImportAttribute on a method, it will resolve it to an external symbol (again, this is a very simplified explanation).
When it finds an ObsoleteAttribute, it emits a warning of deprecation.
Your own attributes (which you can create with a class inheriting from the Attribute base class) will not have an effect on the default compiler. But you (or other libraries) can also scan for them at runtime, opening up many possibilities and leading to your second question:
I typically use them to do meta programming. For example, imagine a custom network server handling packets of a specific format, implemented in different classes. Each packet format is recognized by reading an integer value. Now I need to find the correct class to instantiate for that integer.
I could do that with a switch..case or dictionary mapping integer -> packet which I extend every time I add a packet, but that is ugly since I have to touch code possibly far away from the actual Packet class whenever I add or delete a packet. I may not even know about the switch or dictionary in case the server is implemented in another assembly than my packets (modularity / extensibility)!
Instead, I create a custom PacketAttribute, storing an integer property set via the attribute, and decorate all my Packet classes with it. The server only has to scan through my assembly types at startup (via reflection) and build a dictionary of integer -> packet pairs automatically. Of course I could scan my assembly every time I need a packet, but that's probably a bit slow performance-wise.
There are APIs which are much more attribute heavy, like controllers in ASP.NET Core: You map full request URLs to methods in handler classes with them, which then execute the server code. Even URL parameters are mapped to parameters in that way.
Debuggers can also make use of attributes. For example, decorating a class with the DebuggerDisplayAttribute lets you provide a custom string displayed for the instances of the class when inspecting them in Visual Studio, which has a specific format and can directly show the values of important members.
You can see, attributes can be very powerful if utilized nicely. The comments give some more references! :)
To answer the second part of your questions, they are also used, for example, in setting validation and display attributes for both client and server side use in a web application. For example:
[Display(Name = "Person's age")]
[Required(ErrorMessage = "Persons's age is required")]
[RangeCheck(13, 59, ErrorMessage = "The age must be between 13 and 59")]
public int? PersonsAgeAtBooking { get; set; }
Or to decorate enums for use in display
public enum YesNoOnlyEnum
{
[Description("Yes")]
Yes = 1,
[Description("No")]
No = 2
}
There are many other uses.
We have a system that manages generic physical resources. There are over 500 individual resources. The system is used for many different things and to make the software easier to write we use aliases.
For example, a physical resource TG67I9 is given an alias of "RightDoor". When code is written RightDoor is used instead of TG67I9 making the code more readable. This alias list is loaded as a text file with references to resources and their aliases. This system uses literally hundreds of different alias lists to reference the same physical resources.
This type of setup has two major shortcomings. First, when resources are called using their aliases, they are passed in as strings. Door.Open("RightDoor") for example. This does not give any tooltips or smart anything making the code more difficult to write. It basically requires constantly referencing the alias list. Is it RightDoor or Right_Door or right-door or... you get the idea. The second is that there is no validation of parameters until execution. All the compiler knows is that a string is passed in and then it's happy. Only when the code is run, the function tries to access the resource through its alias and fails because it can't find right-door because it's supposed to be RightDoor. An error is displayed. This requires tedious debugging and running the code over and over to weed out any bad aliases.
Is there a better way to do this? Such that an alias list can be made with a cross-reference of physical resources to their alias names and after the list is made that tooltips could appear suggesting resources. (Assume that a new system could be written from scratch)
I'm using the latest .NET with VisualStudio 2017 and C# to write the code.
The simplest approach is most likely a "string enum":
public class Resources {
public const string
LeftDoor = "TG67I8",
RightDoor = "TG67I9";
}
Sample use:
Door.Open(Resources.RightDoor);
Hovering over .RightDoor in VS shows a tooltip (constant) string Resources.RightDoor = "TG67I9"
Right-clicking .RightDoor and selecting Find All References will show where the variable is used.
Another option can be adding the strings in the Resources section of the Project Properties, and then:
using YourProjectNameSpace.Properties;
...
Door.Open(Resources.RightDoor);
That is a bit slower, because the resource(s) are retrieved at run-time, but allows to load the resources from a custom external file separate from the executable.
Use a static class with constants. I have done the same many times and still do. Plus .NET does this as well.
public static class PhysicalResources
{
public const string One = "Uno";
public const string Two = "Deux";
// ...
}
I have those two entities :
Color entity is mapped to a table of constant values that represent colors.
Code=1, Name="Red"
Code=2, Name="Blue"
And so on...
In Car entity, the Color property is of type int and has a foreign key constraint to the Code property in Color entity. I want to convert the Color property in Car to an Enum, but the Enum should get it's values from Color table.
The Enum could be updated in each build action or an "update model" action in the designer.
Can this functionality can be achieved ?
" but the Enum should get it's values from Color table. "
So whats wrong with what you have? Anyway since you asked...
An enum is by definition inside the assembly. So as soon as a new color is added to the table you have an outdated Enum. But if you are ok with having upto date at build time. There is a good option.
Clearly the suggestion to use T4 is interesting . But the t4 would need to connect to DB and read it. When T4 goes beyond source generation, it can be easier to use a simple app. Unless of course you are already good at t4. So if t4 is a little hard for this task try:
A simple side app, that reads the DB and updates the EnumColor.cs would be plausible.
IE a simple console app. Place as a pre build step. The pre-build reads the DB, rewrites the enum.cs file and the compile/build then follows.
**Easy Alternative: using a Dictionary which you can extend at runtime **
Dictionary<int,string> colors
For me the first question is why? I had a similar technical need but the business need was to help with reporting. Enums works great to make code simpler to read and maintain, but is you have to create a report in say SSRS then you don't have access to the enums (okay I am sure some advanced SSRS users will say you can link in assemblies etc, but that is not the point). We played a bit with a prebuild script (could also run post build) to generate inline scaler function scripts to execute against the db. This way you could do select statements such as:
SELECT Model, fColorNameEnum(Color) FROM Car
This way you do not have to touch you reports again if you add a new element in your enum. I tend to use enums in the implementation of business logic, typically item status or workflow state. Adding a new option thus require adding new logic which means doing it in code. If you are never going to reason over the color value in code, then what is the reason for wanting to put it in an enum rather than just another linked object?
What will be the Regular Expression to get all the property and variables names of any class in c#, I want to parse the *.cs file. that is i want to select any *.cs file as input and it should get the property name of that selected class, as an output.
can any one help!!!....would appreciate for any help i tried very much but not got the actual result every time class name is coming instead of property.
thanks
Jack
There's no way you're going to be able to get exactly what you want with a regular expression because you need semantic context, not just string parsing.
For example, a good first attempt at finding all of the field and property definitions in a C# file might go something like this
^\s*(?:(?:private|public|protected|internal)\s+)?(?:static\s+)?(?:readonly\s+)?(\w+)\s+(\w+)\s*[^(]
That will match properties (public int Foo {...}) and fields (private int foo;) but not methods (protected void Bar()).
The problem is that a regex engine has no concept of the context within which those tokens appear. It will match both foo and bar in this code:
int foo;
void Stuff()
{
int bar;
}
If you happen to know that your code file follows some coding standards, you may have more luck. For example, if you enforce a style rule that all class members must have access specifiers, then you can make the private/public/etc part of that regex non-optional; since those are only permitted at the class level, it will filter out local variables.
There are other options, none of them too attractive at first glance. There is persistent talk from the C# dev team about exposing the C# compiler as a service in some future version of .NET, which would be perfect here, but I wouldn't expect that any time soon. You could purchase a third-party C# parser/analyzer like this one (caveat: I have zero experience with that, it's just the first Google hit). You could try compiling the .cs file using csc and examining the IL, but you'd need to know all of the third-party references.
I have posted a question on here previously asking similar advise, but this project has evolved significantly, so I would like to ask for advice on how the experts would tackle this problem.
First, I will describe what the problem is, then how I have currently looked at it. Please, I want to learn - so do critise my approach/tell me what I can/should do better!
Requirements:
I have a log file decoder. I have three different systems generating log files. Each system is slightly different. There are seven different types of log files. Each log file can be in either ASCII format (human readable) or binary format (not human readable). So there are a lot of different logs - but many are similar. For example, for most, the binary and ascii is the same info in a different form.
There is also one log type which is in a totally different structure, i.e., if a, b and c are different values - each stored 6 times, most logs are type 1. One log is type 2.
type 1: abcabcabcabcabcabc
type 2: aaaaaabbbbbbcccccc
On top of this, each system has a status register. The three systems are all different in this respect. i.e. 7 * 8 bit registers, 3 * 32 bit registers... These need processing after the log is decoded (for the logs that contain the info) and then a chart needs to be plotted for other info (where required).
So, my solution so far:
I have a LogFile struct. This contains a DataTable to contain all the data. Also contains a few strings, such as serial numbers which are read from the log files and some Enums (log type, system type, encoding format)
I have a Parser class. This has some static methods : to Identify what logs are contained within a log file (An ASCII file can contain several different ones - the GUI will find out what is in there, ask the user which one they want and then decode it. Another static method to act as a factory and give back an instantiation of the Parser class - there are 3 types. One generic. One for binary of the (type 2, above) and one for ascii of the (type 2, above).
I have a SystemType class. This contains info such as status register meanings, log structures for each type. I.e. when decoding a type, the GUI will call the 'GetTable, which will give back a DataTable with columns of the fields to read from the file. The Parser can then just cycle through the columns, which will allow it to know what type of variable to read from the file (Int, Single, String, etc).
I have a Reader class. This is abstract and has two child classes - one for ascii, one for binary. So, I can call reader.ReadInt and it will handle appropriately.
There is also a class to generate charts and decode the status register. Status registers are just an array of array of strings, giving name and description of each bit. Perhaps this could be a struct - but does it make a difference? There is also a further class which analyses 3 values in one particular log and if they are present, will insert a column with a value calculated from them (they are strings).
The whole things just isn't very flexible, but I didn't want to write a different class for each of (3*7*2 =) 42 log types! They are too similar, yet different so I think that they would have resulted in a lot of duplicate code. This is why I came up with the idea of the DataTable and a generic Parser.
So, sorry for the long text!
I have a few other questions - I have used a DataTable for the data because I use a DataGridView in the GUI to display all of this to the user. I assumed this would simplify this, but is there a better way of doing this? When I bind the DataTable to the DataGridView, I have to go through each one looking for a particular row to highlight, adding tooltips and setting various column widths, which actually takes as long as the whole decoding process. So if there is a more efficient way of doing this, it would be great!
Thanks for any feedback!! Please, I can not have too much advice here as I have been playing around, rearranging for ages trying to get it in a way that I think is a nice solution, but it always seems clunky and very tightly coupled, espcially with the GUI.
You probably want a class instead of a struct.
I wouldn't use a DataTable unless I had to. I would instead use a List or something similar, you can still bind this to your DataGridView. For formatting the grid, if this is an option, buy a UI control library that will give you more options than the DataGridView does. My favorite is Telerik, but there are a bunch of them. If that isn't an option, then you'll have some custom UI logic (either JavaScript or row binding code behind) that will look at the record your binding and make decisions based on the properties of the class.
As far as the 42 different classes, all with similar code, create an abstract base class with the reusable code, and derive from this class in your different logtype classes, overriding the base functionality where needed.
Use interfaces to separate functionality that must be implemented by the logtype, and implement those interfaces. That way when you are iterating through a list of these classes, you know what functionality will be implemented based interface.
It sounds like you would greatly benefit from using interfaces to separate contract from implementation, and code to the contract to decouple your classes.
Hope this helps.
The only thing that pops out at me is this
I have a LogFile struct
Are you actually getting a benefit from it being a struct that outway the potential pitfalls?
From the guidelines
CONSIDER defining a struct instead of a class if instances of the type
are small and commonly short-lived or
are commonly embedded in other
objects.
DO NOT define a struct unless the type has all of the following
characteristics:
It logically represents a single value, similar to primitive types
(int, double, etc.).
It has an instance size under 16 bytes.
It is immutable.
It will not have to be boxed frequently.