Enum with option to show up second describtion - vb.net

I have some enum inside my code (below) and i am using this enum to show up the names like e.g that: Datasource.Some_server1.ToString(). I am using it either inside code engine to do some calculation if specific server enum is and also to show the name on the webpage. The problem now is my manager asked me to show up diffrent names. So for instance not Some_server1 but for instance: HHGT Server 56. The problem is my code is using those enum names to do some tasks and i cannot just change it within this enum. Do you know some way i can tell inside my project ok now i want see describtion name for this enum so not Some_server1 but now if Datasource.Some_server1.ToString() then show HHGT Server 56. Is there such possibility without not changing my enum in the way rest of code is still using it? Hope you got what i mean.
Public Enum Datasource
Some_server1
Some_server2
Some_server3
Some_server4
End Enum

You can add more context to your Enum by assigning a Description Attribute to each member.
Public Enum DataSource
<Description("HHGT Server 56")> Some_server1
'etcetera
End Enum
Then you can use this function (taken from a really useful extension) to get the Description string:
Public Shared Function GetEnumDescription(ByVal value As [Enum]) As String
Dim fi As Reflection.FieldInfo = value.[GetType]().GetField(value.ToString())
Dim attributes As DescriptionAttribute() = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
Return If((attributes.Length > 0), attributes(0).Description, value.ToString())
End Function

Related

Dynamically Change value of Class Variable at Runtime in VB.Net

I need to be able to change the value the variable "timeMins" at runtime in the JSON container class below. But, the only way that VB.Net allows me to do this is to declare "timeMins" as a Constant - However, constants cannot be changed at runtime as far as I know in VB.net.
Below is what I have so far...It compiles and runs, but does not do what I need it to do.
Const timeMins As String = "15"
Public Class JSON_Container_Real_Time
<JsonProperty(PropertyName:="Meta Data")>
Private Meta As MetaData
<JsonProperty(PropertyName:="Time Series (" + timeMins + "min)")>
Public Time_Series_Daily As Dictionary(Of String, StockInfo)
End Class
In its current state what you're trying to do is not possible. At namespace level you're only allowed to declare types and constants, so you would need to move the variable declaration inside your class in order to be able to make it a non-constant. However, this means that you cannot use it in the JsonProperty attribute, because attributes require constant values only.
You would have to look for another solution to serialize/deserialize you class.

Visual Basic: Read only Visability of Structure members

Ok, so this kind of follows after a previous question that I've asked involving structures and classes. So referencing this question (and I am using classes now for the base) I have one member of the class that is an array (and I know that I have to declare it without dimensions) that as part of the constructor I want it to define the dimensions of the array. When I was initially trying to do the ReDim the compiler was unhappy because I was declaring the member as ReadOnly. While what I'm doing with the array has it's own question of feasibility to it that's not what I'm asking about as it raised a different issue that I must answer first.
Is there a way to make members of a class/structure read only outside of the class/structure but modifiable with in the class/structure without having to use properties or internal functions/subs to gain the read access?
Basically like declaring the member private but you can at least read the member outside the class/structure. Just not anything else.
You can do something like this
Private _some As String
Public Property Some As String
Get
Return _some
End Get
Private Set(value As String)
_some = value
End Set
End Property
No. On its own, there is no way to make a class field public for reading, but private for writing. Accessibility modifiers on a field affect both read and write.
The cleanest way to do what you want is to define a private field in your class, and define a public property getter:
Private _dummy As String
Public Property Dummy() As String
Get
Return _dummy
End Get
End Property
Granted, it would be nice to be able to express this more succinctly, as is possible with C# using auto-implemented properties:
public string Dummy {get; private set;}

Comparing String to class name

I have a little Problem:
I have a method that parses an incoming string for certain values, if a value is found, a new class is instantiated. The class name is identical to the parsed string. At the moment, my code looks like this:
Public Class Test1
End Class
Public Class Important
End Class
Public Class DoWork
Public Sub DoWork(incoming as String)
Select case incoming
case "Test1"
dim myobj as new Test1
Case "Important"
dim myobj as new Important
End Select
End Sub
End Class
I do not like the string literals like "Test1" - i could store them in a constant, but if the class names change, they have to be changed too. Is there a way to replace the literals with the Name of class?
I know that me.gettype produces the result for instantiated objects, but what about the simple name for a class, which is no object at this moment?
If your string is in correct format you can use Type.GetType(string) method to retrieve type. Then you can use Activator class to create instance if you have default constructor on that type.
Rafal's answer is good if you're stuck with the current situation, with the incoming string parameter. But it's still a bit fragile. What if the incoming parameter changes? What if you want to restructure your code, moving some classes to different namespaces or assemblies? What if those strings change - do you now have to rename your classes and recompile? You don't see the magic strings explicitly now, but they're still there.
So ask yourself - where are those strings coming from? Are they generated internally by your code? If so, you might want to generate, instead of strings, an Enum value that corresponds to the class to be instantiated. If they're external strings that you map to your classes, consider having explicit mapping (in a configuration file, for instance) that map String->Type. It's a bit more cumbersome, but a lot more flexible.

How can I create an "enum" type property value dynamically

I need to create a property in a class that will give the programmer a list of values to choose from. I have done this in the past using the enums type.
Public Enum FileType
Sales
SalesOldType
End Enum
Public Property ServiceID() As enFileType
Get
Return m_enFileType
End Get
Set(ByVal value As enenFileType)
m_enFileType = value
End Set
End Property
The problem is I would like to populate the list of values on init of the class based on SQL table values. From what I have read it is not possible to create the enums on the fly since they are basically constants.
Is there a way I can accomplish my goal possibly using list or dictionary types?
OR any other method that may work.
I don't know if this will answer your question, but its just my opinion on the matter. I like enums, mostly because they are convenient for me, the programmer. This is just because when I am writing code, using and enum over a constant value gives me not only auto-complete when typing, but also the the compile time error checking that makes sure I can only give valid enum values. However, enums just don't work for run-time defined values, since, like you say, there are compile time defined constants.
Typically, when I use flexible values that are load from an SQL Table like in your example, I'll just use string values. So I would just store Sales and SalesOldType in the table and use them for the value of FileType. I usually use strings and not integers, just because strings are human readable if I'm looking at data tables while debugging something.
Now, you can do a bit of a hybrid, allowing the values to be stored and come from the table, but defining commonly used values as constants in code, sorta like this:
Public Class FileTypeConstants
public const Sales = "Sales"
public const SalesOldType = "SalesOldType"
End Class
That way you can make sure when coding with common values, a small string typo in one spot doesn't cause a bug in your program.
Also, as a side note, I write code for and application that is deployed internally to our company via click-once deployment, so for seldom added values, I will still use an enum because its extremely easy to add a value and push out an update. So the question of using and enum versus database values can be one of how easy it is to get updates to your users. If you seldom update, database values are probably best, if you update often and the updates are not done by users, then enums can still work just as well.
Hope some of that helps you!
If the values aren't going to change after the code is compiled, then it sounds like the best option is to simply auto-generate the code. For instance, you could write a simple application that does something like this:
Public Shared Sub Main()
Dim builder As New StringBuilder()
builder.AppendLine("' Auto-generated code. Don't touch!! Any changes will be automatically overwritten.")
builder.AppendLine("Public Enum FileType")
For Each pair As KeyValuePair(Of String, Integer) In GetFileTypesFromDb()
builder.AppendLine(String.Format(" {0} = {1}", pair.Key, pair.Value))
End For
builder.AppendLine("End Enum")
File.WriteAllText("FileTypes.vb", builder.ToString())
End Sub
Public Function GetFileTypesFromDb() As Dictionary(Of String, Integer)
'...
End Function
Then, you could add that application as a pre-build step in your project so that it automatically runs each time you compile your main application.

How do I define a list of properties

I have a class called "heater". One of the properties is "designstatus", a string. I want to limit the property to one of three choices; "current", "obsolete", "notdesigned". How would I do this?
You can use an Enum. E.g.:
Public Enum DesignStatus
Current
Obsolete
NotDesigned
End Enum
You can do this using an Enum, but as an Enum is an Integer this isn't going to completely do what you want, so I would suggest doing something similar to this:
Public Enum DesignStatuses
Current
Obsolete
NotDesigned
End Enum
So when you need to get the actual String name of the Enum that you have used you can do:
DesignStatus.ToString("G")
Which will return the actual name of the constant instead of the value.