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.
Related
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;}
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
There are lots of questions floating around about how to create an Enum constraint for generic types. ex1, ex2, ex3 etc.
I was curious if it were possible to go one step further and require only certain locally defined enums as constraints to your generic method.
Currently, I'm using the suggested solution of using structure, Iconvertible constraints on the generic type to handle allowing enums for generic types. That looks something like this in vb.net:
Private Function MyMethod(Of T As {Structure, IConvertible})(ByVal myEnum As T) As Object
'...
End Function
Now what would happen if I wanted to further force the constraint to only two of my enums, defined as follows:
Public Enum EnumOne
Height
End Enum
Public Enum EnumTwo
Width
End Enum
I haven't been able to figure out the syntax yet.
Although I'm programming in VB.net, C# answers are welcome as well.
No, you cannot constrain the type argument like that, these enum types have nothing in common. There is not much value in a generic function that could handle only two type argument types, it is much simpler to just provide two non-generic overloads of the functions:
Private Function MyMethod(ByVal value as EnumOne) As Object
'' etc
End Function
Private Function MyMethod(ByVal value as EnumTwo) As Object
'' etc
End Function
With perhaps another private method that provides the common implementation for these functions.
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.
In VB.NET, I am trying to talk to a webservice (that can't be changed) to create and update customer data.
The CreateCustomer service expects an object of type ConsumerPerson and the ChangeCustomer service expects an object of type ChangeData.
The properties of these two object are exactly the same, so I thought it would be wise to just set the properties using one single function.
However, I am unable to find a way to tell my function that I want to fill either the ConsumerPerson or the ChangeCustomer object.
How do I make this work without late binding problems?
An interface sounds like your best approach. Here is a short code snippet. I picked a simple property named "Name" of type string. It should be easy to modify with the actual properties on your class.
Public Interface ICustomerData
ReadOnly Property Name As String
End Interface
Public Class ConsumerPerson
Implements ICustomerData
Public ReadOnly Property Name As String Implements ICustomerData.Name
Get
return _name
End Get
End Property
End Class
Public Class ChangeData
Implements ICustomerData
Public ReadOnly Property Name As String Implements ICustomerData.Name
Get
return _name
End Get
End Property
End Class
use an interface !
declare an interface IFoo, and implement its members in your subclasses ConsumerPerson and ChangeCustomer. That's exactly what interfaces are for.
You create an interface which both classes implements.
Is it not possible to overload your function with the second data type?
If you cannot change your objects, but they share the same field names, you could xml serialize the data and deserialize as the other class. - You should strongly consider the performance implications of this; however, it would give you the functionality you're asking for.