Confusion about the Argument< T > and Variable< T > in .NET 4.0 Workflow Foundation - .net-4.0

I am using Windows Workflow Foundation in .NET 4.0. Below is some syntax/semantic confusion I have.
I have 2 equivalent way to declare an Assign activity to assign a value to a workflow variable (varIsFreeShipping).
(1) Using XAML in the designer.
(2) Using code.
But in approach 2, the it seems I am creating a new OutArgument< Boolean > and assign value to it, not to the original Variable< Boolean> varIsFreeShipping. And OutArgument and Variable are totally different types.
So how could the value assigned to this new Argument finally reach the original Variable?
This pattern seems common in WF 4.0. Could anybody shed some light on this?
Thanks!

As a matter of fact, the second (2) method can be written just as:
Then = new Assign<bool>
{
To = varIsFreeShipping,
Value = true
}
This all works because OutArgument<T> can be initialized through a Variable<T> using an implicit operator.
In your first (1) assign, using the editor, that's what's happening behind the scene; the variable is being implicitly converted from Variable to OutArgument.
WF4 uses alot of implicit operators mainly on Activity<T> from/to Variable<T>, OutArgument<T> from/to Variable<T>, etc. If you look at it, they all represent a piece of data (already evaluated or not), that is located somewhere. It's exactly the same as in C#, for example:
public int SomeMethod(int a)
{
var b = a;
return a;
}
You can assign an argument to a variable, but you can also return that same variable as an out argument. That's what you're doing with that Assign<T> activity (using the variable varIsFreeShipping as the activity's out argument).
This answers your question?

Related

VB.Net Alternative to C# Underscore (discard)

In c# i can do:
_ = Bla();
Can I do that in VB.Net ?
I think the answer is no but I just wanted to make sure.
The underscore (_), as used in your example, is C#'s discard token. Unfortunately, there is (currently) nothing similar in VB. There is a discussion about adding a similar feature on the VB language design github page.
In your example, however, you can just omit assigning the result (both in C# and VB), i.e.
Bla(); // C#
Bla() ' VB
The "discard variable" is particularly useful for out parameters. In VB, you can just pass an arbitrary value instead of a variable to discard unused ByRef parameters. Let me give you an example:
The following two lines are invalid in C#:
var b = Int32.TryParse("3", 0); // won't compile
var b = Int32.TryParse("3", out 0); // won't compile
Starting with C# 7, you can use _ for that purpose:
var b = Int32.TryParse("3", out _); // compiles and discards the out parameter
This, however, is perfectly valid in VB, even with Option Strict On:
Dim b = Int32.TryParse("3", 0)
So, yes, it would be nice to make the fact that "I want to ignore the ByRef value" more explicit, but there is a simple workaround in VB.NET. Obviously, once VB.NET gets pattern matching or deconstructors, this workaround won't be enough.

a middle approach between Dynamic Typing and Static Typing

I wanted to ask if anyone knows of a programming language where there is dynamic typing but the binding between a name and a type is permanent. Static typing guards your code from assigning a wrong value into a variable, but forces you to declare(and know) the type before compilation. Dynamic typing allows you to assign values with a different type to the same variable one after the other. What I was thinking is, it would be nice to have dynamic typing, but once the variable is bound, the first binding also determines the type of the variable.
For example, using python-like syntax, if I write by mistake:
persons = []
....
adam = Person("adam")
persons = adam #(instead of persons += [adam])
Then I want to get an error(either at runtime or during compilation if possible) because name was defined as a list, and cannot accept values of type Person.
Same thing if the type can not be resolved statically:
result = getData()
...
result = 10
Will generate a runtime error iff getData() did not return an integer.
I know you can hack a similar behavior with a wrapper class but it would be nice to have the option by default in the language as I don't see a good legitimate use for this flexibility in dynamic languages(except for inheritance, or overwriting a common default value such as null/None which could be permitted as special cases).

how to find out if a c++/cli heap variable has <undefined value>

I've not been using C++ for about 4 years and came back to it a month ago, and that was where I also have first heard about the CLI extension. I still have to get used to it, but this website helps a lot! Thank you!! Anyway, I couldn't find an answer to the following problem:
When I declare a variable
int iStack;
then it is declared but not defined, so it can have any value like
iStack = -858993460
depending on what the value at the stack position is, where the variable is created.
But when I declare a variable on the heap
int^ iHeap
then as far as I know the handle is created but the variable is not instantiated (don't know if you call it instantiation here) or defined and I can only see
iHeap = <Nicht definierter Wert> (which means <undefined value>)
Is there any way to detect if this value is defined?I particularly don't need it for int, but for example for
array<array<c_LocationRef^,2>^>^ arrTest2D_1D = gcnew array<array<c_LocationRef^,2>^>(2);
to find out if the elements of the outer or inner array are instantiated (I'm sure here it is an instantiation ;-) )
arrTest2D_1D = {Length=2}
[0] = {Length=20}
[1] = <Nicht definierter Wert> (=<undefined value>)
As far as I know, the CLR automatically initialise your variables and references in C++ CLI.
In .NET, the Common Language Runtime (CLR) expressly initializes all
variables as soon as they are created. Value types are initialized to
0 and reference types are initialized to null.
To detect if your variable is initialised, you should compare the value of your hat variable to nullptr :
int^ iHeap;
if(iHeap == nullptr){
Console::WriteLine(L"iHeap not initialised");
}
This works on my VS2010 ; it outputs iHeap not initialised
It should work for your specific problem as well (arrays).
By the way, value types are initialised to zero hence your first example should output 0 (I've tested it, and it does output 0) :
int iStack;
Console::WriteLine(L"iStrack = {0}", iStack); // outputs 0
Quote is from codeproject
MSDN page for nullptr
EDIT: Here is an other quote, from Microsoft this time :
When you declare a handle it is automatically initialized with null, so it will not refer to anything.
Quote from MSDN see the paragraph "Tracking Handles"

cli/c++ increment operator overloading

i have a question regarding operator overloading in cli/c++ environment
static Length^ operator++(Length^ len)
{
Length^ temp = gcnew Length(len->feet, len->inches);
++temp->inches;
temp->feet += temp->inches/temp->inchesPerFoot;
temp->inches %= temp->inchesPerFoot;
return temp;
}
(the code is from ivor horton's book.)
why do we need to declare a new class object (temp) on the heap just to return it?
ive googled for the info on overloading but theres really not much out there and i feel kinda lost.
This is the way operator overloading is implemented in .NET. Overloaded operator is static function, which returns a new instance, instead of changing the current instance. Therefore, post and prefix ++ operators are the same. Most information about operator overloading talks about native C++. You can see .NET specific information, looking for C# samples, for example this: http://msdn.microsoft.com/en-us/library/aa288467(v=vs.71).aspx
.NET GC allows to create a lot of lightweight new instances, which are collected automatically. This is why .NET overloaded operators are more simple than in native C++.
Yes, because you're overloading POST-increment operator here. Hence, the original value may be used a lot in the code, copied and stored somewhere else, despite the existance of the new value. Example:
store_length_somewhere( len++ );
While len will be increased, the original value might be stored by the function somewhere else. That means that you might need two different values at the same time. Hence the creation and return of a new value.

Lambdas with captured variables

Consider the following line of code:
private void DoThis() {
int i = 5;
var repo = new ReportsRepository<RptCriteriaHint>();
// This does NOT work
var query1 = repo.Find(x => x.CriteriaTypeID == i).ToList<RptCriteriaHint>();
// This DOES work
var query1 = repo.Find(x => x.CriteriaTypeID == 5).ToList<RptCriteriaHint>();
}
So when I hardwire an actual number into the lambda function, it works fine. When I use a captured variable into the expression it comes back with the following error:
No mapping exists from object type
ReportBuilder.Reporter+<>c__DisplayClass0
to a known managed provider native
type.
Why? How can I fix it?
Technically, the correct way to fix this is for the framework that is accepting the expression tree from your lambda to evaluate the i reference; in other words, it's a LINQ framework limitation for some specific framework. What it is currently trying to do is interpret the i as a member access on some type known to it (the provider) from the database. Because of the way lambda variable capture works, the i local variable is actually a field on a hidden class, the one with the funny name, that the provider doesn't recognize.
So, it's a framework problem.
If you really must get by, you could construct the expression manually, like this:
ParameterExpression x = Expression.Parameter(typeof(RptCriteriaHint), "x");
var query = repo.Find(
Expression.Lambda<Func<RptCriteriaHint,bool>>(
Expression.Equal(
Expression.MakeMemberAccess(
x,
typeof(RptCriteriaHint).GetProperty("CriteriaTypeID")),
Expression.Constant(i)),
x)).ToList();
... but that's just masochism.
Your comment on this entry prompts me to explain further.
Lambdas are convertible into one of two types: a delegate with the correct signature, or an Expression<TDelegate> of the correct signature. LINQ to external databases (as opposed to any kind of in-memory query) works using the second kind of conversion.
The compiler converts lambda expressions into expression trees, roughly speaking, by:
The syntax tree is parsed by the compiler - this happens for all code.
The syntax tree is rewritten after taking into account variable capture. Capturing variables is just like in a normal delegate or lambda - so display classes get created, and captured locals get moved into them (this is the same behaviour as variable capture in C# 2.0 anonymous delegates).
The new syntax tree is converted into a series of calls to the Expression class so that, at runtime, an object tree is created that faithfully represents the parsed text.
LINQ to external data sources is supposed to take this expression tree and interpret it for its semantic content, and interpret symbolic expressions inside the tree as either referring to things specific to its context (e.g. columns in the DB), or immediate values to convert. Usually, System.Reflection is used to look for framework-specific attributes to guide this conversion.
However, it looks like SubSonic is not properly treating symbolic references that it cannot find domain-specific correspondences for; rather than evaluating the symbolic references, it's just punting. Thus, it's a SubSonic problem.