简体   繁体   中英

How Can I Modify The UInteger Type In Visual Basic .NET?

What I'm looking to do is to make a Structure that will be named Percent. Its range will be an Integer from 0 to 100 , and can be used just a normal Type, ie:

Dim a as Integer

So:

Dim b as Percent

I tried creating a class but I immediately understood that Integer is a structure and not a class. Looking in the MSDN library I couldn't find much.

Solution


As simon at rcl posted, the idea is to make a structure similar to an Integer type, and limit the values it can accept through the Value->Set section.

 Public Structure Percent Dim PValue As Integer Public Property Value As UInteger Get Return PValue End Get Set(ByVal value As UInteger) 'Make sure the value is valid... If value > 100 Then Throw New PercentTooBigException("You cannot give a percentage value greater than a 100.") ElseIf value < 0 Then Throw New PercentTooSmallException("You cannot give a percentage value smaller than 0.") End If '... and if it is set the local PValue to the value value. PValue = value End Set End Property End Structure 

Usage then will be: Dim c as Percent Dim d as Percent c.Value = 99 d.Value = 26 If c.Value > d.Value Then End

The con in this solution of mine is that you can't set a value like: Dim e as Percent = 24 Instead, you need to access the Value property and have an operation on it: Dim f as Percent f.Value = 23 '(As seen in the example above).

You can overload the CType operator using a Widening conversion for an implicit conversion. You will have to overload it for each type that you want to assign in this manner.

Then you can use code like this:

Dim pcnt As Percent = 42
Console.WriteLine("The percent is {0}%", pcnt)

Code:

Public Structure Percent
    Dim PValue As UInteger

    Public Sub New(value As Integer)
        Me.PValue = CType(value, UInteger)
    End Sub

    Public Property Value As UInteger
        Get
            Return PValue
        End Get
        Set(ByVal value As UInteger)
            'Do something with invalid values
            If value > 100 Then
                PValue = 100
            Else
                If value < 0 Then
                    PValue = 0
                Else
                    PValue = value
                End If
            End If
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return PValue.ToString()
    End Function

    Public Shared Widening Operator CType(ByVal p As Integer) As Percent
        Return New Percent(p)
    End Operator
End Structure

This is going to be quite a lot of work. The start is relatively easy (apologies for the C#):

public struct Percent
{
    private uint pcnt;

    public Percent(int value)
    {
        this.pcnt = (uint)value;
        if (this.pcnt > 100)
        {
            throw new ArgumentOutOfRangeException("Value > 100");
        }
    }
    public uint Value
    {
        get { return this.pcnt; }
        set
        {
            if (value > 100)
            {
                throw new ArgumentOutOfRangeException("Value > 100");
            }
            this.pcnt = value;
        }
    }
}

This can be used as follows:

    Percent p  = new Percent(57);
    Console.WriteLine("Value = {0}", p.Value);
    Percent p2 = new Percent(44);
    Console.WriteLine("Value = 0", p2.Value);
    p2.Value = p.Value - 10;

The reason you can't do Percent p= 57; is because although that can be written for int etc in VB or C#, the compiler special cases it and generates extra code behind the scenes.

Now the hard work starts. You want to type Percent p2 = p * p2 - but my question is what does this mean? The two values we have after the code above are 57 and 47; I think multiplying any value by a Percentage of eg 57% is actually multiplying by 57 / 100. So you'll have to decide what you mean by multiplication and then override the multiply op and code it up. This will also need overrides for any numeric type you might want to use: int32, int64, decimal, uint32, uint64, anything else you might use. Once you've done all those you can write things like decimal adjusted = 123.45 * p;

You then repeat this for any other operation you might want to use, like addition for example. I can see adding two percentages together might be useful (what happens if they sum to > 100?), but adding a percentage to an int or other numeric? What does that do?

Conversely, dividing one percentage by another doesn't make a lot of sense to me, but dividing a Percent by an int does (as does dividing an int by a Percent).

Then there are the interfaces which need to be implemented. UInt implements IComparable, IFormattable, IConvertible, IComparable, and IEquatable. You probably should also implement these (or be prepared to when you find you need them).

So work out your answers for all the operations, code up the op overrides, add and implement the interfaces you'll need and there you are!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM