Best vb.net questions in December 2010

EF4: LINQ 2 Entities query works in C# but not in VB

7 votes

[EDITED: I left the original question below, with some more context and code to reproduce the problem. The short version below contains the essence of the question]

Short version: the query below throws a System.NotSupportedException: "Unable to cast the type 'System.Linq.IOrderedQueryable1' to type 'System.Linq.IQueryable1'. LINQ to Entities only supports casting Entity Data Model primitive types." The exception is only raised in the VB.Net version. When translated to C#, no exception is raised.

   Dim doesThisCrash = From outerOrder In orders
        Where outerOrder.ProductId =
        (From p In products Join o In orders On p.Id Equals o.ProductId
         Order By p.Id
         Select p.Id).FirstOrDefault()
        Select outerOrder
    doesThisCrash.ToList()

So, to make it crash, it seems that we need a subquery where the original ObjectSet (orders) is joined with another ObjectSet (products), and ordered. When using just the orders or the products set, no crash occurs. When leaving out the Order By, also no crash.

I'm inclined to think this is a (VB.Net) compiler bug, unless there is something obvious that I'm overlooking here...

For now my question still stands:

  • why does a seemingly exact same query work in C# but not in VB?
  • can this query be made to work in VB.Net?

[/EDIT]

Optional, longer version (original question):

My domain looks very different, but I translated the problem to a simpler version, with the following entities (note: I actually defined these using the .edmx designer, so this is a simplified version):

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime DateCreated { get; set; }
    }

    public class Order
    {
        public int Id { get; set; }
        public int CustomerId { get; set; }
        public int ProductId { get; set; }
        public DateTime OrderDate { get; set; }
    }

    public class Customer
    {
        public int Id { get; set; }
    }

I'm trying to work out a linq-to-entities query that should strucurally look like this, in VB.Net:

    Dim db = New SampleEntities()
    Dim orders As IQueryable(Of Order) = db.Orders
    Dim products As IQueryable(Of Product) = db.Products
    Dim currentDate = DateTime.Now

    Dim qLinq = From outerOrder In orders
                Where outerOrder.OrderDate = currentDate AndAlso
                outerOrder.ProductId =
                    (From p In products Join o In orders On p.Id Equals o.ProductId
                     Where o.OrderDate = outerOrder.OrderDate AndAlso
                            outerOrder.CustomerId = o.CustomerId
                     Order By p.DateCreated
                     Select p.Id).FirstOrDefault()
                Select outerOrder

This raises a System.NotSupportedException:

"Unable to cast the type 'System.Linq.IOrderedQueryable1' to type 'System.Linq.IQueryable1'. LINQ to Entities only supports casting Entity Data Model primitive types."

When leaving out the 'Order By' part, no exception is raised.

I don't really see a reason why this query would not be supported... So I decided to try the same thing in C#:

var qLinq = from oOut in orders
            where oOut.OrderDate == currentDate
                  && oOut.ProductId == 
                          (from p in products join o in orders on p.Id equals o.ProductId
                           where oOut.OrderDate == o.OrderDate 
                           && oOut.CustomerId == o.CustomerId
                           orderby p.DateCreated
                           select p.Id).FirstOrDefault()
                    select oOut;

To my surprise, this works! Then I translated the C# query to extension method syntax, and then back to VB, but got the same results (the C# version works, the VB.Net version raises the same exception).

So I guess my question is twofold:

  • why does a seemingly exact same query work in C# but not in VB?
  • can this query be made to work in VB.Net?

For reference, here are the queries in extension method syntax:

C# version:

        var q = orders.Where(outerOrder => 
            outerOrder.OrderDate == currentDate &&
            outerOrder.ProductId == 
            (products
                .Join(orders, 
                    f => f.Id, 
                    o => o.ProductId,
                    (f, o) => new { f, o })
                .Where(t => t.o.OrderDate == outerOrder.OrderDate 
                           && outerOrder.CustomerId == t.o.CustomerId)
                .OrderByDescending(t => t.f.DateCreated)
                .Select(t => t.f.Id))
                .FirstOrDefault());

VB.Net version:

    Dim q = orders.Where(Function(outerOrder) outerOrder.OrderDate = currentDate AndAlso
                             outerOrder.ProductId = (products.Join(orders,
                               Function(p) p.Id,
                               Function(o) o.ProductId,
                               Function(p, o) New With {.p = p, .o = o}).
                           Where(Function(x) x.o.OrderDate = outerOrder.OrderDate AndAlso
                                     outerOrder.CustomerId = x.o.CustomerId).
                           OrderByDescending(Function(x) x.p.DateCreated).
                           Select(Function(x) x.p.Id).
                           FirstOrDefault()))

Moving the Order By p.DateCreated line as per my edited answer allows the query to run without any exceptions. However, the emitted SQL is different so I don't think you are getting back the correct result.

Dim qLinq = From outerOrder In orders
            Let id = (From p In products 
                      Order By p.DateCreated
                      Join o In orders On p.Id Equals o.ProductId
                      Where o.OrderDate = outerOrder.OrderDate AndAlso
                            outerOrder.CustomerId = o.CustomerId
                      Select p.Id).FirstOrDefault()
            Where outerOrder.OrderDate = currentDate AndAlso
                  outerOrder.ProductId = id
            Select outerOrder

Why code snippet in VB is more featured than in C# ?

7 votes

As I read http://msdn.microsoft.com/en-us/library/ms165394.aspx:

For VB:

Inside the Snippet element, add the References element and all of the required child elements that add a reference to the project when the snippet is inserted.

For C#

Visual C# code snippets to do not support the References section, so a reference to System.Windows.Forms.dll must be added to the project manually

What fundamental reason prevents C# to support References like VB ?

Update: I saw this posted http://visualstudiogallery.msdn.microsoft.com/en-us/dc06b54c-b6c4-4cf5-8203-a09c6979e881

But it isn't even as full-featured as Code Snippet References as Code Snippet References will allow you to add multiple references at once not just one by one.

C# is supposedly more "professional" than VB.NET, one would expect C# to be more featured not more limited or does "professional" means you have to do it the hard way as said "MANUALLY" :p

When will the C# team catch up with VB.NET team ?

Karen Liu of the C# IDE team responded to this in a feedback report:

Thanks for submitting this suggestion. This is something we are aware of and had tried to do as a Design Change Request before. Ultimately, based on cost to implement this where we were in the product cycle, we made the tough decision that since references would be something you would need to add only once, this did not make it into VS2005. This is something we are looking to do in the future though and hearing feedback on this is valuable.

Only nine upvotes, not enough to make it a popular request. I'd recommend you vote it up, they do pay attention to that.

Why is this code returning different values? ( C# and VB.NET )

6 votes

VB.NET Code:

Module Module1

Sub Main()
    Dim x, y As Single
    x = 0 + (512 / 2 - 407) / 256 * 192 * -1
    y = 0 + (512 / 2 - 474) / 256 * 192
    Console.WriteLine(x.ToString + ": " + y.ToString)
    Console.ReadLine()
End Sub

End Module

Returns: 113,25: -163,5

C# Code:

class Program
{
    static void Main(string[] args)
    {
        float x, y;
        x = 0 + (512 / 2 - 407) / 256 * 192 * -1;
        y = 0 + (512 / 2 - 474) / 256 * 192;
        Console.WriteLine(x + ": " + y);
        Console.ReadLine();
    }
}

returns 0: 0

I don't get it, would appreciate an explanation.

C# / performs integer division, truncating the fractional portion. VB.NET implicitly casts to Double.

To perform floating point division, cast to a floating point type:

    static void Main(string[] args)
    {
        float x, y;
        x = 0 + (512 / 2 - 407) / (float)256 * 192 * -1;
        y = 0 + (512 / 2 - 474) / (float)256 * 192;
        Console.WriteLine(x + ": " + y);
        Console.ReadLine();
    }

.NET events special methods (add/remove/raise/other)

6 votes

Hi,

I was wondering about the EventInfo.GetRaiseMethod and EventInfo.GetOtherMethods methods. Apparently, the CLR supports 4 kinds of methods associated with events: add, remove, raise, and "others". But events created in C# only have add and remove... I assumed that raise was used in VB, since you have to specify a RaiseEvent method when you declare a custom event, but apparently it's not the case: GetRaiseMethod always returns null.

So, does anyone know:

  • what's the point in having a raise method associated with an event if it's never used? Is there a specific MSIL instruction to raise an event using this method? (I couln't find anything like it in the opcodes)
  • what are the "other" methods returned (well, not returned actually) by GetOtherMethods? What's are they supposed to do?
  • are there types in the BCL that implement those special methods?

As far as I know, raise isn't used much, and I've practically never seen it used. C++/CLI is pretty much the only language I know that make it easy to declare a raise method. See this code for example:

using namespace System;

ref class Foo {

private:
    Action ^bar;

public:
    event Action ^Bar {
        void add (Action ^action)
        {
            Console::WriteLine ("add");
            bar += action;
        }

        void remove (Action ^action)
        {
            Console::WriteLine ("remove");
            bar -= action;
        }

        void raise ()
        {
            Console::WriteLine ("raise");

            if (!bar)
                return;

            Console::WriteLine ("raise for real");
            bar->Invoke ();
        }
    };
};

void hello ()
{
    Console::WriteLine ("hello");
}

void main ()
{
    Foo ^foo = gcnew Foo ();
    foo->Bar ();

    foo->Bar += gcnew Action (&hello);

    foo->Bar ();
}

Which, when being run, naturally outputs:

C:\tmp>test
raise
add
raise
raise for real
hello

To answer your question, there's no opcode to invoke an event, the compiler will just emit a call to the raise method:

  IL_0020:  ldloc.0
  IL_0021:  call       instance void Foo::raise_Bar()

Just like it emits a call to add_Bar.

It's also worth nothing that as C# allows you to invoke an event exclusively in the scope of the type which declares the member event, you can't get C# code to call that raise method. So no, you won't find such a method exposed in the BCL.

As for the .other kind of methods, I've never seen any attached to an event. And I only saw them used once for properties, and neither the book «Inside IL assembler» nor «The CLI annotated standard» give any information about them. But basically, they allow you to attach methods to a property or to a event to bind them semantically. They're neither a addon, nor a removeon, nor a raise method, but they would be part of the event, should a language need to express that. In the meantime, the only way to emit one is to use ilasm.

What is raw code of textbox

5 votes

May be i can get some negative points on this question but, really this question is boggling in my mind from last many days that what is the basic/raw code behind textbox(or other such controls).

i mean i understands that, we can inherit the textbox class and make our changes, we creates its object and use it.

but wants to know how that class creates a textbox(the design which allow us to enter text) (same query for other components), is it a code of 'C' language which are generating it using CG (computer graphics) programming or any other thing.

Experts please resolve my curiosity.

Thanks

Windows provides several basic API's for drawing on the screen. You can draw pixels, lines, boxes and more complex geometric shapes. There are also API's to draw text. Other API's allow you to react to user input, e.g. mouse movement and clicks and keyboard input.

From these basic API's you can create your own text box by drawing the exact pixels of how the text box should look and react to user input. However, Windows has a built-in concept of a text box. This text box has a standard look and feel and is also integrated with UI concepts like focus, tab order, the clipboard and the caret. But behind the scenes Windows is using the low level API functions to draw on the screen and react to user input.

When you create a TextBox in Windows Forms it actually creates and wraps a standard Windows Edit control. This control is drawn using GDI. However, other programming models like WPF may create TextBox controls that looks like a normal text box but uses a custom implementation supplied by WPF and is drawn using DirectX.

How to secure .NET DLL's

5 votes

What is best practice for securing DLL's for projects you are working on? Certain DLL's I am interested in developing will have data access layer (DAL) and business logic layer (BLL) functionality. There may be several apps that can eventually hit these DLL's to perform business specific functions.

What is the best way to secure these DLL's so they can only be used by only creator's applications?

Security for both blocking unauthorized use of the DLL's and security against possible decompilation are both desirable.

One option might be to mark all the exposed classes in your DLL as "internal" instead of "public", then use the "InternalsVisibleTo" attribute in your DLL to explicitly name the DLLs (and possibly exes) that are allowed to use your internal types. This may require all participants to be strongnamed, but that's a good thing to do anyway.

Ultimately, there is no absolute way to prevent a determined hacker from accessing your code when your code is executing on the hacker's machine. All code that can be executed by the machine can be disassembled and reassembled into something else with sufficiently advanced tools and experience.

The best way to approach code security is to ask the question "How difficult do we want to make it for someone to use this code without license or authorization, and how much time/money are we willing to spend to achieve that?" If you do nothing, it's very easy for someone to use your DLLs in some other project. If you do a few simple things, you can make it inconvenient for someone to use your DLLs elsewhere. If you invest months of effort, you might be able to make it very difficult for someone to misuse your code, but you can never make it impossible.

One technique that is as close to absolutely secure as I can imagine is: don't execute your code on the client's (or hacker's) machine at all. Run a web service instead, and keep your code on the server where a hacker can't casually fire up a debugger on your process or disassemble your code. Your code security is then defined by the physical security at the server location and network access security to the server's ports. These attack vectors are many orders of magnitude more difficult to circumvent than anything you can do to code that executes on the hacker's machine.

For some software companies, moving a portion of their applications from the client to the cloud isn't about getting better scalability or easier updates or lower costs, it's about code security and piracy prevention.

How to simulate C++ friend in C# and VB.NET?

5 votes

Because sometimes, I really need a friend.

I can think of the following tricks:

  1. Read only wrapper - like ReadOnlyCollection. The friend keeps the pointer to the modifiable object, while everyone else can access only the wrapper.
  2. Write delegate - the friend gives the constructor of the object a reference to a delegate as one of the parameters, the constructor fills it with an address to a private method that can be used to modify the object.
  3. Reflection - obviously a bad idea. Included for completeness.
  4. Multiple assemblies - put your friends together in a separate assembly and set your modifier methods internal.
  5. Expose the modifiable object, but add comments to modifier methods "This is an infrastructure method - don't call it!"
  6. Nested classes.
  7. Add System.ComponentModel.EditorBrowsable(System.ComponentModel. EditorBrowsableState.Never) attribute to the member you want only the friend to access to hide it from IntelliSense.
  8. Implicit interface implementation - see comments.

Is this list exhaustive? Can anyone sort these in order of decreasing performance? Order of decreasing neatness? Any suggestions when to use which?

You can also use the InternalsVisibleTo attribute.

For a given assembly, A, you can specify which other assemblies can have access to A's internal types.

Parsing a CAD or BIM file and fetching/exporting the 'Layer Name'...

4 votes

Sound-byte Question: How easy or difficult is it to parse a CAD/BIM file and return(export) just the names of those 'Layers, Sheets, or Worksets' contained within?

More Detailed Question:

I'm a practicing architect (not the software kind, but the building/construction kind) and we are entertaining the development of a custom product that monitors CAD/BIM files within a folder or set of folders and continually returns the names of the 'Layers', 'Sheets', and 'Worksets' contained within each file. In other words, if someone creates a layer called 'Electrical Wiring' within a (AutoCad, Revit, Microstation, or ArchiCad) file, for example, how difficult would it be to parse, fetch, and export that 'layer name' to another program, once the file was saved and updated? Just the 'layer name', 'sheet name', or 'workset name' and nothing else.

I realize I have no 'bounty' or 'reputation' to put forward for an answer, but I do have my own "Whuffies" in the area of 'architectural design' and could perhaps, as return for an answer, sketch you the cooliest little greenhouse/gazebo/deck/porch/spa/sunroom you've ever seen! ;) Afterall, I figure a return to local economies will save our overall economy, why can't these 'local economies' be digital and web-based economies as well? :)

Stop by my 'office' to take a look at our work: :) http://www.flickr.com/photos/studiowikitecture/sets/72157604538587139/

Thanks for your time. Cheers, Ryan

.............

Also wanted to include the following for clarification, if necessary.... (let me know if you need further clarification)

What are 'Layers'? Within CAD files and to some extend BIM files, 'Layers' are used organize common objects, for example... Exterior Wall Layer, Interior Wall Layer, Electrical Layer, Electrical Wiring Layer, Framing Layer, Slab Layer, Duct Layer..etc..etc.

What are 'Sheets'? Within both CAD/BIM files, 'Sheets' are used to compose, or turn off/on certain 'layers'. An 'electrical floor plan' for example, will have the 'electrical layer' and the 'wall layer' turned on, and superimposed on each other. Other layers, like the 'duct layer' would be turned off.

What are 'Worksets'? Worksets, are kind of like layers, but are more specific to BIM programs. They represent ways the user can 'break' up the BIM model into logical divisions of labor... for example. a workset for just the structural columns a workset for electrical panel and substations. a workset for just a 'wing' of a building etc...etc.

As a reference, if it matters, the following popular CAD/BIM programs are associated with the following languages and standards.

Revit: C#, C++, VB.NET, .NET, EXPRESS/STEP (file ext: .rvt)

AutoCad: C++, AutoLISP, Visual LISP, VBA, .NET and ObjectARX, STEP/EXPRESS (file ext: .dwg, .dxf)

Microstation: C/C++, VBA, .NET., STEP/EXPRESS (file ext: .dgn)

ArchiCAD: C/C++, GDL, BASIC, Visual Studio, Codewarrior, STEP/EXPRESS (file ext: .pla)

VectorWorks: C/C++, VB, STEP/EXPRESS

I think using a standard approach is the way to go here. STEP stands for "Standard for the Exchange of Product model data". It is also known as ISO 10303.

As you've pointed out, vendors implements the STEP standard, i.e. they allow users to export data in a STEP-File (ISO 10303-21) and/or STEP-XML files.

Once you've export the data in a STEP-File, you can theoretically parse it and extract the 'layer name', 'sheet name', or 'workset name' or whatever data from it. Tools are available to help you do that.

If you post the exported STEP-File you get from one of the tools you mentioned above, it would help to see what can be extracted.

Mark non-unique rows in a DataTable

4 votes

Hi,

I have a DataTable which I want to check if values in three of the columns are unique. If not, the last column should be filled with the line number of the first appearance of the value-combination.

For example, this table:

ID    Name    LastName    Age    Flag
-------------------------------------
1     Bart    Simpson     10      -
2     Lisa    Simpson      8      -
3     Bart    Simpson     10      -
4     Ned     Flanders    40      -
5     Bart    Simpson     10      -

Should lead to this result:

Line  Name    LastName    Age    Flag
-------------------------------------
1     Bart    Simpson     10      -
2     Lisa    Simpson      8      -
3     Bart    Simpson     10      1
4     Ned     Flanders    40      -
5     Bart    Simpson     10      1

I solved this by iterating the DataTable with two nested for loops and comparing the values. While this works fine for a small amount of data, it gets pretty slow when the DataTable contains a lot of rows.

My question is: What is the best/fastest solution for this problem, regarding that the amount of data can vary between let's say 100 and 20000 rows?
Is there a way to do this using LINQ? (I'm not too familiar with it, but I want to learn!)

Okay, I think I got an answer myself. Based on the suggestion in James Wiseman's answer, I tried something with LINQ.

Dim myErrnrFnct = Function( current, first) If(first <> current, first, 0)
Dim myQuery = From row As DataRow In myDt.AsEnumerable _
                      Select New With { _
                        .LINE = row.Item("LINE"), _
                        .NAME = row.Item("NAME"), _
                        .LASTNAME = row.Item("LASTNAME"), _
                        .AGE = row.Item("AGE"), _
                        .FLAG = myErrnrFnct(row.Item("LINE"), myDt.AsEnumerable.First(Function(rowToCheck) _
                                                                                        rowToCheck.Item("NAME") = row.Item("NAME") AndAlso _
                                                                                        rowToCheck.Item("LASTNAME") = row.Item("LASTNAME") AndAlso _
                                                                                        rowToCheck.Item("AGE") = row.Item("AGE")).Item("LINE")) _
                      }

With this query I get exactly the result that's described in the Question. The myErrnrFnct Function is necessary because I want the Flag column to have the value 0 if there is no other row with the same values.

To get a DataTable out of myQuery again, I had to add some extensions described here:
How to: Implement CopyToDataTable Where the Generic Type T Is Not a DataRow
And then, this line will do:

Dim myNewDt As DataTable = myQuery.CopyToDataTable()

This seems to work just fine. Any suggestions to do this better?

Dim intResult As Integer = Nothing

4 votes

VB.NET compiles:

Dim intResult As Integer = Nothing

C# does not:

int intResult = null; // cannot convert

How the result finally goes to MSIL?

More that than, VB code is OK:

If intResult > Nothing Then

EDIT

OK, MS says:

Assigning Nothing to a variable sets it to the default value for its declared type.

But it tells nothing about Nothing comparation.

Nothing in VB.NET is actually equivalent to default(Type) in C#.

So int intResult = default(int); is the C# equivalent.

According to the VB.NET Language Reference: "Assigning Nothing to a variable sets it to the default value for its declared type. If that type contains variable members, they are all set to their default values."


Edit: Regarding the comparison to Nothing: I'm guessing intResult > Nothing is interpreted as intResult > 0, because the compile-time type of intResult is Integer, which has a default value of 0. If the type of intResult is not known at compile time (e.g., it is a boxed Integer), I suspect that this would not compile.

See the Community Content section at the bottom of the VB.NET Language Reference page for a similar example (Nothing < 2).

Communication between a desktop application and a web application

4 votes

I have a desktop and web application connected to same database. Which is the most preferred method to make them communicate with each other?

You should use SOA and then both your desktop app and web app should communicate with the Service.

And the Service will be responsible for communicating with the database.

Can i change the width of a line chart?

4 votes

Is it possible to change the width of a line series with the chart bundled in .net 4? How would i do it?

But i still havent found what i'm looking for...

i dont think it's possible from a property. Find the right answer and the reputation is yours :)

VB.net - "Dim x as new Y()" vs "Dim x as Y = new Y()"

4 votes

In our VB.net codebase I occasionally see Dim x as new Y(), where Y is a class.

What is this code doing and how does it differ to the more common Dim x as Y = new Y()"?

Thanks.

They are exactly the same; the first is just a shortcut:

http://msdn.microsoft.com/en-us/library/Aa903373

Why Can't I Use a "New" Expression As a Statement in VB.NET?

4 votes

Why can't I start a line using a parenthesis followed by the keyword new?? For example:

(New <custom_obj>).foo(var)

In that case is obvious that I'm trying to avoid creating a named instance of the the <custom_obj> because I know that I'll only be using it at that sentence.

Note that actually creating a named instance is not a problem for me... I just wanna know the reason why this is not possible.

Do you want a language lawyer answer? Look in the VB.NET Language Specification, beginning at 10. Statements. The simplest answer is that the word “Expression” does not appear on that page. NewExpression is explicitly distinct from InvocationExpression, so you can use an InvocationExpression in an InvocationStatement, but you can only use a NewExpression in a LocalDeclarationStatement or in the context of some greater expression.

More handwavingly, the VB.NET syntax is designed to be easy to read, write and parse, and one way it accomplishes this is by being careful about what’s a Statement and what’s an Expression. Python is similar — an assignment is a statement and not an expression. There’s no reason for every language to be exactly like C.

But, as chibacity points out, you can work around this with the Call statement:

call new object.toString

will compile successfully. Try to make your classes meaningful, instead.

Sharing code between 2 projects without a dll

3 votes

How can I have code-sharing between two projects without making a dll?

The issue is: I have a tool that syncs users & groups from LDAP to a database.

Now the tool is a windows service, but testing it as such is very difficult and time consuming.

Which is why I made a console application where I can test the LDAP syncing, and then just copy the respective sourcecode-files over to the service project.

But... keeping the common files in sync is a bit of a problem. I don't want to make a dll, because this probably creates me a problem with the 3rd project, a windows installer (for the service) where I have to use ExecutingAssembly path...

Is there a way to share the code without making a separate dll? Automagic statical linking, so to say ?

How about adding a file as a link.

In Visual Studio right click on your console test app project -> select add existing file -> in the file add dialog navigate to files in your actual windows service project -> select the files you want to share -> and on add button select add as link option.