ASP.NET (VB) Extension Method not working as expected - asp.net

I have the following Extension Method
Imports System.Runtime.CompilerServices
Namespace Extensions
Public Module IntegerExtensions
<Extension()>
Public Function ToCommaDeliminatedNumber(ByVal int As Integer) As String
Dim _input As String = int.ToString
Select Case int
Case Is > 99999 : Return _input.Remove(_input.Length - 3) & "k"
Case Is > 9999 : Return Math.Round(Double.Parse(int / 1000), 1).ToString & "k"
Case Is > 999 : Return String.Format("{0:N0}", int)
Case Else : Return _input
End Select
End Function
End Module
End Namespace
And in one of my classes I'm using
user.Reputation.ToCommaDeliminatedNumber
I am importing the Extensions Namespace into the Class, but the error I'm getting is...
'ToCommaDeliminatedNumber' is not a member of 'Integer?'.
Can anybody tell me what I might be missing here? I do have other Extension Methods for Strings and Dates that work exactly as expected... I'm just at a loss on this one.

Judging from your error message it looks like user.Reputation is actually a Nullable(Of Integer), based on the trailing question mark ('Integer?'). Is that correct?
Your extension method is extending Integer, not Integer? (i.e., Nullable(Of Integer)), hence the error. So either provide an overload that handles Integer? or call Value on the nullable type:
user.Reputation.Value.ToCommaDeliminatedNumber()
You will need to check that it is not null (Nothing) otherwise an exception will be thrown. An overloaded method might look like this:
<Extension()>
Public Function ToCommaDeliminatedNumber(ByVal int As Integer?) As String
Return int.GetValueOrDefault().ToCommaDeliminatedNumber()
End Function
In the case that it's null the default value of 0 would be displayed.

Related

Ada: Using a private variable in a precondition of a public function

The following is an attempt to produce my problem with the minimum code (it is not intended to be a useful program).
My problem is that I want to make a precondition on a public function dependent on a private variable. I have to declare my function before the "private" indicator and my variables after that indicator. This means that I get the compilation error
problem.ads:10:16: "secondPrivateVariable" is undefined
problem.ads:10:40: "firstPrivateVariable" is undefined
I have tried putting placeholder definitions above the function, but then I get compilation errors about conflicting definitions.
package Problem is
pragma Elaborate_Body (Problem);
function publicAPI(which : Positive) return Natural with
Pre => secondPrivateVariable > firstPrivateVariable;
-- should only be called when second > first
private
-- the following variables are used by many procedures and
-- should be kept private
firstPrivateVariable : Natural := 7;
secondPrivateVariable : Natural := 465;
end Problem;
Any assistance would be welcomed.
You could wrap the check in a function:
function Call_Permitted return Boolean;
function publicAPI(which : Positive) return Natural with
Pre => Call_Permitted;
private
firstPrivateVariable : Natural := 7;
secondPrivateVariable : Natural := 465;
function Call_Permitted return Boolean is
(secondPrivateVariable > FirstPrivateVariable);
If Call_Permitted is only to be used locally and only to generate object code if assertions are enabled, you could say
function Call_Permitted return Boolean with Ghost;
(this is a SPARK-related feature, probably only available in GNAT)

Return Default Value When No Match Found

I have a function GetQuantity that returns a decimal. In some cases I want to return nothing i.e. and empty string so that ' ' is displayed.
Actual Behavior:
GetQuantity(1) -> 1.0
GetQuantity(2) -> 2.0
GetQuantity(3) -> 3.3
Desired Behavior:
GetQuantity(1) -> 1.0
GetQuantity(2) -> 2.0
GetQuantity(3) -> ' '
In case 3 I can obviously return -1.0 or something but that is not what I need.
FUNCTION GetQuantity RETURNS DECIMAL(INPUT num AS INTEGER):
DEFINE VARIABLE quantity AS DECIMAL NO-UNDO FORMAT "->,>>>,>>9.9<<<<<<<<".
quantity = 3.3. //initialization is neccessary as IRL my value is initialized
IF num = 1 THEN DO:
RETURN 1.0.
END.
ELSE IF num = 2 THEN DO:
RETURN 2.0.
END.
RETURN quantity. //base case return ' '
END.
DISPLAY GetQuantity(3)
One way would be to return ? in case of the default and handle this in your output routine.
As ? is also the result of a failing calculation (div by 0) this might be dangerous.
The alternative would be to write a class with a Value property and a Default flag and an ToString() override.
BLOCK-LEVEL ON ERROR UNDO, THROW.
USING Progress.Lang.*.
CLASS Test.SampleValueHolder:
DEFINE PUBLIC PROPERTY Value AS DECIMAL NO-UNDO
GET.
PRIVATE SET.
DEFINE PUBLIC PROPERTY IsDefault AS LOGICAL NO-UNDO
GET.
PRIVATE SET.
CONSTRUCTOR PUBLIC SampleValueHolder (pdeValue AS DECIMAL,
plDefault AS LOGICAL):
ASSIGN THIS-OBJECT:Value = pdeValue
THIS-OBJECT:IsDefault = plDefault .
END CONSTRUCTOR.
METHOD PUBLIC OVERRIDE CHARACTER ToString ():
IF THIS-OBJECT:IsDefault THEN
RETURN "" .
ELSE
RETURN STRING (THIS-OBJECT:Value, "->,>>>,>>9.9<<<<<<<<") .
END METHOD.
END CLASS.
Now you can either RETURN NEW SampleValueHolder (1.0, FALSE) or RETURN NEW SampleValueHolder (?, TRUE) into a Variable of Type Test.SampleValueHolder.
And whenever you display STRING () of that value, you either get the formatted value or "" when it's the default.
An alternative solution to Mike's above would be to change getQuantity() to return a Character value instead of the decimal it currently does. Although of course this could cause a lot of work fixing all the calling points. I don't know the extent of its use.
Also, if you're in a position where the number of conditions is greater than you've shown, a CASE would be far easier to maintain than lots of IF statements. Something like this:
FUNCTION GetQuantity RETURNS CHARACTER(INPUT num AS INTEGER):
DEFINE VARIABLE quantity AS CHARACTER NO-UNDO INITIAL "3.3".
CASE num:
WHEN 1 THEN quantity = "1.0".
WHEN 2 THEN quantity = "2.0".
OTHERWISE quantity = "".
END CASE.
RETURN STRING(quantity).
END.
DISPLAY GetQuantity(3).

Simple broken For Each Loop in VB6

I am writing a Contains method for vb6 collections that hold strings.
However I cannot get the syntax right on my foreach.
What should I change?
Public Function Contains(col as Collection, key as Variant) as Boolean
Dim thing as Object '// this is the key
For Each thing in col
If CStr(key) = CStr(thing) then
Contains = True
Exit Function
End If
Next
Contains = False
End Function

Ada interface casting?

I am trying to model a set of Parsers in Ada based on interface below:
package Parsers is
type Parser is interface;
type DataArray is array(Integer range <>) of String(1..100);
function Parse(Object : access Parser; FilePath : String) return DataArray is abstract;
end Parsers;
The first Parser interface member is a text parser show below:
with Parsers;
package TextParsers is
type Parser is new Parsers.Parser with null record;
overriding function Parse(Object : access Parser; FilePath : String) return Parsers.DataArray;
end TextParsers;
with Parsers;
use Parsers;
package body TextParsers is
overriding function Parse(Object : access Parser; FilePath : String) return Parsers.DataArray is
Data : Parsers.DataArray (0..144);
begin
-- just stubbed out
return Data;
end Parse;
end TextParsers;
And finally, I would like to have a factory method create these Parsers based on the path provided, like detecting if it was a txt file or maybe a csv, etc. Here is the factory code:
with Parsers;
use Parsers;
package ParserFactories is
function GetParser(Path : String) return Parsers.Parser;
end ParserFactories;
with Parsers, TextParsers;
package body ParserFactories is
function GetParser(Path : String) return Parsers.Parser is
Text : TextParsers.Parser;
Parse : Parsers.Parser'Class := Text;
begin
return Parse;
end GetParser;
end ParserFactories;
I keep getting a "dynamically tagged expression not allowed" compilier error, and I cannot figure out how I can create these objects that implement the Parser interface and return it out of this function. Is there a way to do this in Ada?
You are trying to return a Parsers.Parser type. This is not allowed (and not what you intend to do). Change it to Parsers.Parser'Class instead.
The answer is that you don't return the interface's type, but the type that the object is... or else you can return the interface'class to indicate that you're going to assign it to that abstract-typed variable.
Procedure Testing is
package Interface_Test is
Type IBob is interface;
Function Make Return IBob is abstract;
Function Image( Object : In IBob ) Return String is abstract;
Generic
Type Data is (<>);
Default_Data : In Data;
Package Container is
Type Data_Container is NEW IBob with private;
private
Type Data_Container is new IBob with record
Info : Data:= Default_Data;
end record;
Overriding Function Make Return Data_Container;
Overriding Function Image(Object : In Data_Container) Return String;
end Container;
end Interface_Test;
package Body Interface_Test is
Package Body Container is
Function Make Return Data_Container is
begin
Return Result : Data_Container;
end Make;
Function Image( Object : Data_Container ) Return String is
begin
return Data'Image( Object.Info );
end image;
end Container;
end Interface_Test;
package J is new Interface_Test.Container( Integer, 1 );
use type J.Data_Container;
Test : J.Data_Container:= J.Make;
Use Ada.Text_IO;
Begin
put_line( Test.Image );
End;

VB - dll, string character output

I’m trying to obtain data from a dll, but I do not know how to do it.
My code is:
'Function
Public Declare Function SET_XML_PATH Lib "EbmPapstFan.dll" (ByRef ruta As String) As Long
Public Declare Function GET_PRODUCTS Lib "EbmPapstFan.dll" (ByRef ruta As String) As Long
Sub Selec()
Dim ruta As String
Dim Int_A As Long, Int_B
ruta = "C:\ebmpapst\data\AC\"
Int_A = SET_XML_PATH(ruta) 'If Int_A=0 then they aren't mistake
Int_B = GET_PRODUCTS("")
Worksheets("Selec").Range("E2").Value = Int_B 'Nº products
End sub
Results are:
Int_A= 0
Int_B= 18
This isn't a mistake with the path because Int_A is 0. In addition, GET_PRODUCTS gives me the number of products that software has. The manual say that this function also has string character output.
The primary problem is that I don’t know how obtain this other string character output.
vb dll strange output in C#
Both outputs of the declared functions are "Long" and not "String" so there's no way that they're outputting anything except that.
I'd recommend revisiting the manual you refer to, to see exactly how it is documented and what the string value's function call would be.
The 2 function declaratons show long as the return types, however, the string being passed in is going in byRef and not byVal. It is possible that the string value is being returned via that parameter being adjusted inside the call.
More details about the documentation would be helpful.

Resources