Best vb.net questions in July 2011

MyClass equivalent in C#

14 votes

In looking at this question, commenter @Jon Egerton mentioned that MyClass was a keyword in VB.Net. Having never used it, I went and found the documentation on it:

The MyClass keyword behaves like an object variable referring to the current instance of a class as originally implemented. MyClass is similar to Me, but all method calls on it are treated as if the method were NotOverridable.

I can see how that could kind of be useful, in some specific scenarios. What I can't think of is, how would you obtain the same behaviour in C# - that is, to ensure that a call to a virtual method myMethod is actually invoked against myMethod in the current class, and not a derived myMethod (a.k.a in the IL, invoking call rather than callvirt)?

I might just be having a complete mental blank moment though.

According to Jon Skeet, there is no such equivalent:

No, C# doesn't have an equivalent of VB.NET's MyClass keyword. If you want to guarantee not to call an overridden version of a method, you need to make it non-virtual in the first place.

An obvious workaround would be this:

public virtual void MyMethod()
{
    MyLocalMethod();
}

private void MyLocalMethod()
{
    ...
}

Then you could call MyLocalMethod() when a VB user would write MyClass.MyMethod().

Why do lambda expressions in VB differ from C#?

9 votes

I just came across a bug in NHibernate which happens to already be raised: https://nhibernate.jira.com/browse/NH-2763

I'm not sure if this applies to anything else other than enums but when using a Lambda from VB, it looks different to the same Lambda from C#.

C#:

Where(x => x.Status == EmployeeStatus.Active)

VB

Where(Function(x) x.Status = EmployeeStatus.Active)

They are the same as far as I'm aware? (My VB isn't great)

If I put a break point on the same line of code, where the above code is passed into. In C# I get:

C# version

On the same line when VB version is passed in, I get:

VB version

Is this something I'm doing wrong? Is the result's the same, just displayed different between C#/VB?

Edit: Ok so they are displayed different, but they can't be the same because NHibernate cannot handle it. The C# version is handled perfectly fine by NHibernate, the VB version resolves in the following exception being thrown:

Exception

The NHibernate StackTrace:

   at NHibernate.Impl.ExpressionProcessor.FindMemberExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 168
   at NHibernate.Impl.ExpressionProcessor.ProcessSimpleExpression(Expression left, Expression right, ExpressionType nodeType) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 323
   at NHibernate.Impl.ExpressionProcessor.ProcessSimpleExpression(BinaryExpression be) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 316
   at NHibernate.Impl.ExpressionProcessor.ProcessBinaryExpression(BinaryExpression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 418
   at NHibernate.Impl.ExpressionProcessor.ProcessExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 486
   at NHibernate.Impl.ExpressionProcessor.ProcessExpression[T](Expression`1 expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 504
   at NHibernate.Criterion.QueryOver`2.Add(Expression`1 expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Criterion\QueryOver.cs:line 635
   at NHibernate.Criterion.QueryOver`2.NHibernate.IQueryOver<TRoot,TSubType>.Where(Expression`1 expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Criterion\QueryOver.cs:line 686
   at *removed*.EmployeeRepository.GetByEntityId(Int64 entityId, Expression`1 basicCriteria) in D:\*removed*\EmployeeRepository.cs:line 76

So something must be different between the two?

Edit 2:

For Jonathan. This is the method where the expression is used:

public IEnumerable<Employee> GetByEntityId(long entityId, Expression<Func<Employee, bool>> basicCriteria)
{
    IEnumerable<Employee> result;

    using (var tx = Session.BeginTransaction())
    {
        var employeeQuery = Session.QueryOver<Employee>()
                                    .Where(x => x.EntityId == entityId);

        if (basicCriteria != null)
            employeeQuery = employeeQuery.Where(basicCriteria);

        result = employeeQuery.List();

        tx.Commit();
    }

    return result;
}

The difference you are seeing has nothing to do with lambdas; it is simply a difference in the semantics of the languages. VB is emitting calls to functions that by default throw exceptions if an integer overflows (hence the Checked part of the name).

By default the C# compiler does not emit the "checked" version of functions, and apparently NHibernate is developed by C# users, so it doesn't seem to recognize the "checked" functions.

If you go to the Compile options for your project and click on Advanced Compile Options, you can check the "Remove integer overflow checks" box so that VB has the default C# behavior and you shouldn't get that error anymore:

Screenshot of dialog showing option

VB.NET linq group by with anonymous types not working as expected

6 votes

I was toying around with some of the linq samples that come with LINQPad. In the "C# 3.0 in a Nutshell" folder, under Chater 9 - Grouping, there is a sample query called "Grouping by Multiple Keys". It contains the following query:

from n in new[] { "Tom", "Dick", "Harry", "Mary", "Jay" }.AsQueryable()
group n by new
{
    FirstLetter = n[0],
    Length = n.Length
}

I added the string "Jon" to the end of the array to get an actual grouping, and came up with the following result:

C# LINQPad result

This was exactly what I was expecting. Then, in LINQPad, I went to the VB.NET version of the same query:

' Manually added "Jon"
from n in new string() { "Tom", "Dick", "Harry", "Mary", "Jay", "Jon" }.AsQueryable() _
group by ng = new with _
{ _
    .FirstLetter = n(0), _
    .Length = n.Length _
} into group

The result does not properly group Jay/Jon together.

VB.NET LINQPad result

After pulling my hair out for a bit, I discovered this MSDN article discussing VB.NET anonymous types. In VB.NET they are mutable by default as opposed to C# where they are immutable. In VB, you need to add the Key keyword to make them immutable. So, I changed the query to this (notice the addition of Key):

from n in new string() { "Tom", "Dick", "Harry", "Mary", "Jay", "Jon" }.AsQueryable() _
group by ng = new with _
{ _
    Key .FirstLetter = n(0), _
    Key .Length = n.Length _
} into group

This gave me the correct result:

enter image description here

So my question is this:

  1. Why does mutability/immutability of anonymous types matter when linq does an equality comparison? Notably, in Linq-to-SQL it doesn't matter at all, which is likely just a product of the translation to SQL. But in Linq-to-objects it apparently makes all the difference.
  2. Why would MS have chosen to make VB's anonymous types mutable. I see no real advantage, and after mucking around with this issue I see some very real disadvantages. Namely that your linq queries can have subtle bugs.

-- EDIT --

Just an interesting extra piece of info... Apparently this is keyed property issue is widely known. I just didn't know what to Google for. It's been discussed here and here on stackoverflow. Here's another example of the issue using anonymous types and Distinct:

Dim items = New String() {"a", "b", "b", "c", "c", "c"}
Dim result = items.Select(Function(x) New With {.MyValue = x}).Distinct()
Dim result2 = items.Select(Function(x) New With {Key .MyValue = x}).Distinct()
'Debug.Assert(result.Count() = 3) ' Nope... it's 6!
Debug.Assert(result2.Count() = 3)

The Key modifier doesn't just affect mutability - it also affects the behaviour of Equals and GetHashCode. Only Key properties are included in those calculations... which clearly affects grouping etc.

As for why it's different for VB - I don't know. It seems odd to me too. I know I'm glad that C# works the way it does though :) Even if it could be argued that making properties optionally mutable makes sense, I don't see why it should be the default.

VB.NET web developer wanting to learn C#

6 votes

I've been an ASP.NET VB.NET Web Developer for the past 4 years, but its been mainly self-taught so I think theres a fair few basics I have probably not learnt along the way.

I'm interested in switching to C#, and was wondering what book would be best to buy to learn this.

Is Jon Skeet's 'C# in depth' book a good place to start learning, or would this be too difficult for me to start with?

I hope this question hasn't already been asked, and my apologies if it has!

This is probably a duplicate; but yeah - I think that would be an excellent book.

I think you'll find it easier than you think to make the transition. A large part of what you probably do already is really part of the .Net Framework and not VB.NET. That will remain unchanged when you are using C#.

I won't say, 'It's just syntax'; but it's 'mostly just syntax'. Regardless, I think if you read/work through C# in Depth you'd leaps and bounds ahead of most C# devs I've seen.

Silverlight - Is there a performance difference between C# and VB.net Event Handlers?

5 votes

Being new to both .NET and Silverlight, I have noticed that many of the tutorials for Silverlight (Tim Heuers Blog, Silverlight TV etc) are in C#. I know that the general difference between VB and C# is usually preference.

However one of the major differences I had noticed was the way C# and VB.NET handle events. Is this just a syntactical difference, or is one or the other optimized to handle events better? For example, they both get compiled down to the same Intermediate Language, but is the code that is generated identical? Seeing as Silverlight relies on this heavily, I thought it might be worth consideration.

Considering the expertise on this forum, I was wondering if anyone has done research into this, or performance testing.

The code that gets generated may not be identical down to the instruction, but the overall effect is the same. You should not see a performance difference in that area.

VB.NET has two syntaxes for events - AddHandler, which is the same as C#'s +=, and Handles, which is just syntactic sugar for AddHandler in a constructor.

WPF MVVM implementing the viewmodel to reflect the base model?

5 votes

Something that has been confusing me for a while now with WPF MVVM is for example, when I have a base model containing nothing but a few properties and some validation code and I then build a view model around this base model, how should the view model be structured.

For Example:

Base Model ->

Imports ModellingHelper
Imports FTNHelper
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations

Public Class Parser
    Inherits BaseModel

    <Required(ErrorMessage:="Name is required.")>
    Public Property Name As String
        Get
            Return GetValue(Function() Name)
        End Get
        Set(value As String)
            SetValue(Function() Name, value)
        End Set
    End Property

    <Required(ErrorMessage:="Description is required.")>
    Public Property Description As String
        Get
            Return GetValue(Function() Description)
        End Get
        Set(value As String)
            SetValue(Function() Description, value)
        End Set
    End Property

    Public Property InputHeaderInfo As InputHeader
        Get
            Return GetValue(Function() InputHeaderInfo)
        End Get
        Set(value As InputHeader)
            SetValue(Function() InputHeaderInfo, value)
        End Set
    End Property

    Public Property InputVariables As ObservableList(Of Variable)
        Get
            Return GetValue(Function() InputVariables)
        End Get
        Set(value As ObservableList(Of Variable))
            SetValue(Function() InputVariables, value)
        End Set
    End Property

    Public Property OutputVariables As ObservableList(Of Variable)
        Get
            Return GetValue(Function() OutputVariables)
        End Get
        Set(value As ObservableList(Of Variable))
            SetValue(Function() OutputVariables, value)
        End Set
    End Property

    Public Sub New()
        Name = "New Parser"
        Description = "This is a new parser."
        InputHeaderInfo = New InputHeader()
        InputVariables = New ObservableList(Of Variable)
        OutputVariables = New ObservableList(Of Variable)
    End Sub
End Class

ViewModel ->

Imports WinTransform.DataModel
Imports System.IO
Imports WPFHelper
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations
Imports ModellingHelper
Imports Omu.ValueInjecter

Namespace ViewModels
    Public Class ParserViewModel
        Inherits ViewBase

#Region "Properties"
        Public Property Source As Parser
            Get
                Return GetValue(Function() Source)
            End Get
            Set(value As Parser)
                SetValue(Function() Source, value)
            End Set
        End Property

        Public Property InputFile As FileInfo
            Get
                Return GetValue(Function() InputFile)
            End Get
            Set(value As FileInfo)
                SetValue(Function() InputFile, value)
                NotifyPropertyChanged(Function() InputFileContents)
                NotifyPropertyChanged(Function() InputFileParseLine)
                NotifyPropertyChanged(Function() TabVisability)
            End Set
        End Property

        Public ReadOnly Property InputFileContents As String
            Get
                If Not InputFile Is Nothing Then
                    Dim mReader = InputFile.OpenText()
                    Try
                        Return mReader.ReadToEnd()
                    Catch ex As Exception
                        MessageBox.Show(String.Format("Failed to load transform file contents: {0}", ex.Message))
                    Finally
                        mReader.Close()
                    End Try
                End If
                Return String.Empty
            End Get
        End Property

        Public ReadOnly Property InputFileParseLine As String
            Get
                If Not InputFile Is Nothing Then
                    Dim mReader = InputFile.OpenText()
                    Try
                        Dim mLines = mReader.ReadToEnd().Split(vbNewLine).Select(Function(l As String) l.Trim())
                        Dim mLineNo = Source.InputHeaderInfo.TitleLinesFixed + Source.InputHeaderInfo.TitleLinesSkipped + Source.InputHeaderInfo.ColumnHeaderLines + Source.InputHeaderInfo.LinesFixed + Source.InputHeaderInfo.LinesSkipped
                        If mLineNo >= 0 And mLineNo < mLines.Count() Then
                            Return mLines(mLineNo)
                        End If
                    Catch ex As Exception
                        MessageBox.Show(String.Format("Failed to load transform file contents: {0}", ex.Message))
                    Finally
                        mReader.Close()
                    End Try
                End If
                Return String.Empty
            End Get
        End Property

        Public ReadOnly Property TabVisability As Visibility
            Get
                If Not InputFile Is Nothing Then
                    Return Visibility.Visible
                End If
                Return Visibility.Hidden
            End Get
        End Property

        Public ReadOnly Property InputVariablesViews As ObservableList(Of VariableViewModel)
            Get
                Dim mVars As New ObservableList(Of VariableViewModel)
                For Each mVar In Source.InputVariables
                    mVars.Add(New VariableViewModel(mVar))
                Next
                AddHandler mVars.CollectionChanged, Sub() Source.InputVariables.RefreshList(mVars.Select(Function(v As VariableViewModel) v.Source))
                Return mVars
            End Get
        End Property

        Public ReadOnly Property OutputVariablesViews As ObservableList(Of VariableViewModel)
            Get
                Dim mVars As New ObservableList(Of VariableViewModel)
                For Each mVar In Source.OutputVariables
                    mVars.Add(New VariableViewModel(mVar))
                Next
                AddHandler mVars.CollectionChanged, Sub() Source.OutputVariables.RefreshList(mVars.Select(Function(v As VariableViewModel) v.Source))
                Return mVars
            End Get
        End Property

        Public Property IsSaved As Boolean
            Get
                If String.IsNullOrEmpty(SaveFile) Then
                    Return False
                End If

                If Not IsValid Then
                    Return False
                End If

                Return GetValue(Function() IsSaved)
            End Get
            Set(value As Boolean)
                SetValue(Function() IsSaved, value)
            End Set
        End Property

        Public Property SaveFile As String
            Get
                Return GetValue(Function() SaveFile)
            End Get
            Set(value As String)
                SetValue(Function() SaveFile, value)
            End Set
        End Property
#End Region

#Region "Commands"
        Public ReadOnly Property SelectInputFile As ICommand
            Get
                Return New RelayCommand(Sub() SelectInputFileExecute())
            End Get
        End Property

        Private Sub SelectInputFileExecute()
            Dim mOpenDialog = OpenDialog
            If mOpenDialog.ShowDialog() Then
                InputFile = New FileInfo(mOpenDialog.FileName)
            End If
        End Sub
#End Region

        Public Sub New()
            Source = New Parser()
            Init()
        End Sub

        Public Sub New(ByVal mFileInfo As FileInfo)
            Source = LoadParser(mFileInfo)
            SaveFile = mFileInfo.FullName
            Init()
        End Sub

        Public Sub Init()
            AddHandler PropertyChanged, Sub() IsSaved = False
            AddHandler Source.InputHeaderInfo.PropertyChanged, Sub() NotifyPropertyChanged(Function() InputFileParseLine)
        End Sub

        Public Shared Function LoadParser(ByVal mFileInfo As FileInfo) As Parser
            Try
                Dim xmlParser As New XmlDataModel.Parser()
                xmlParser.FromXmlFile(mFileInfo.FullName)
                Dim baseParser As New Parser()
                baseParser.InjectFrom(New ParserInjectionXml(baseParser, xmlParser), xmlParser)
                Return baseParser
            Catch ex As Exception
                MessageBox.Show(String.Format("Could not open parser: {0}", ex.Message))
                Return New Parser()
            End Try
        End Function

        Public Sub Save()
            If String.IsNullOrEmpty(SaveFile) Then
                Dim mSaveDialog = SaveDialog
                If mSaveDialog.ShowDialog() Then
                    SaveFile = mSaveDialog.FileName
                Else
                    Return
                End If
            End If
            IsSaved = Save(SaveFile)
        End Sub

        Public Function Save(ByVal mFilePath As String) As Boolean
            SaveFile = mFilePath
            Return SaveParser(mFilePath, Source)
        End Function

        Public Shared Function SaveParser(ByVal mFilePath As String, ByVal mParser As Parser) As Boolean
            If Not mParser.IsValid Then
                Return False
            End If

            Try
                Dim xmlParser As New XmlDataModel.Parser()
                xmlParser.InjectFrom(New ParserInjectionXml(mParser, xmlParser), mParser)
                xmlParser.ToXmlFile(mFilePath)
                Return True
            Catch ex As Exception
                MessageBox.Show(String.Format("Could not save parser: {0}", ex.Message))
                Return False
            End Try
        End Function
    End Class
End Namespace

What I am wondering is, if there is a better way to structure the view model to improve data binding, so I don't have to bind to Source.Name etc. How should I handle the base model in the view model?

Thanks, Alex.

It really depends.

If your Model already implements INotifyPropertyChanged and uses collection types that implement INotifyCollectionChanged, I personally feel that directly encapsulating and binding to "Source.Name" in XAML has some real advantages - mainly, it dramatically reduces the amount of code, and it (more importantly) reduces the amount of unnecessary code duplication.

However, Model classes often aren't designed specifically with WPF or Silverlight support in mind, and require wrapping. As soon as you have to wrap parts of the Model into the ViewModel for handling specific notifications, wrapping the entire model leads to more consistency.

This really has a cost-benefit trade-off to consider. If you're working with a different designer, wrapping everything leads to consistency in the API (that the designer uses), which can help reduce bugs (at the cost of some extra duplication on your part). If you're doing everything, then it's really up to you what makes the most sense.

DotNetNuke module Page_Load fires twice

5 votes

My module's Page_Load event is firing twice for each "actual" load. On the initial load both loads' Page.IsPostBack property is false.

I've renamed Page_Load to Module_Load to verify the name wasn't an issue. I've made sure the method isn't handling both Me.Load and MyBase.Load, which has been the case in the past.

The only thing I'm doing out of the ordinary is that my module is inheriting from an intermediate base class. Could this be the culprit?

My module:

Namespace Modules.RedactedNamespace
    Public Class List
        Inherits RedactedModuleBase

        Protected Sub Module_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not Me.Page.IsPostBack Then
                BindList()
            End If
        End Sub

    End Class
End Namespace

My base:

Namespace Modules.RedactedNamespace
    Public MustInherit Class RedactedModuleBase
        Inherits DotNetNuke.Entities.Modules.PortalModuleBase

    End Class
End Namespace

Edit (This fixed it) - I had an Image without an ImageUrl. Presumably this is set by my CollapsiblePanelExtender but rendered with a blank src.

This can happen if you have an img tag with an empty src attribute.

I know this sounds strange, but I believe it has to do with the web browser trying to figure out how to load the image with a blank SRC.

I don't know the protocols involved, but I'd bet there is some ambiguity regarding how to resolve empty string.

So, in the case of some browsers, it actually fires a web request to the current URL hoping the image comes back.

Sounds like a reasonable assumption, but it just so happens to break many ASP.Net web forms.

How Many Objects Inside of a Class is too Many?

4 votes

I'm fairly new to the concepts of OO programming - actually programming in general as I am still a student. I'm currently working as an intern in a department that has me coding a new structure that will probably be the base for all their applications to come. So I believe I have the idea behind OO down where you create "basic building blocks" and then expand, expand and expand, until you arrive at the most complex object (for the time being).

I need to put all these "advanced" objects into one but how many is too many? Can I have 100 objects inside of this bigger object if it requires all these "parts".

I really hope this question makes sense to everyone. I'm sure the answer is not going to be a definite answer either but I just need a rule of thumb to go by. I'd really hate to have 100 objects inside of 1 big one if there is a better design/programming technique.

Thank you.

EDIT 1: Thank you so much for your responses but I'm still a little unclear. I already marked an answer as I felt I can continue with what I have but...

Let me continue with my Human Example. A human is composed of many parts (or objects) and each part is also made up of parts, all the way down to a single cell.

Human --> Arm --> Hand --> Fingers --> Thumb --> Bones --> Bone Cells

Human: ojbLeft_Arm, objRight_Arm, objLeftLeg, objRightLeg, objBrain, objHeart, objLeft_Eye, objRight_Eye.... get my point? How many objects inside the human object are too many? Obviously this Human object is going to be considered massive since a Human is very complex. Do you break down the Arm and Leg objects into objLimbs which then stores them?

I guess as another question: if you don't want many objects, HOW do you avoid them?

100 objects inside a single object isn't strictly inappropriate, but it's definitely indicative that there might be a better way to do it. Consider grouping similar objects into composite objects where functionality is similar for usage in your final "superobject". As a rule of thumb, the number of objects you refer to in a class is a (rough) estimate of the complexity of that object; 100 would indicate a complexity that's too high. Note that you can reduce the effective complexity by grouping objects together into composite objects, thereby increasing your overall object count but reducing your direct reference count within your "superobject".

Edit in response to OP's edit and question: The key to the grouping is really all about your expected usage and your problem domain. Consider your Human example; the appropriate breakdown of the object model is really dependent upon the usage your data model is going to be put to. The key here is recognizing that you're NOT trying to represent all possible objects or underlying reality; you're creating a representation that's appropriate to your expected usage. For example, if you were modeling a Human for a cardiologist, it might be appropriate to have a Human object, under which you would have a Heart object, a Circulatory System object, etc.; under the Heart object you might have Left Ventricle, Right Ventricle, etc.. However, for a dentist, your model would still have a Human at the top, but that Human would likely have a Teeth collection at the next level; the Teeth might include objects for Canines, Incisors, etc.

The key point here is that the underlying object (Human) is the same; the representation is completely different. Your cardiologist doesn't care (much) about your teeth, and your dentist doesn't care similarly about your ventricles of your heart. Usage defines representation. So for your case, you have to determine exactly what your usage is, and that usage can (hopefully) define a clear path to your representation.

Count child record and show zero if empty

4 votes

I'm fine with both C# and VB.NET

I have two tables. Authors and Books. It's a one to many relationship, Authors to Books. I'm writing a query to show how many books that each author has.

I wrote the following query:

Dim query = From oa In db.Authors _
         Group oa By oa.Book Into grouping = Group _
         Select Author = Book, Count = grouping.Count(Function(s) s.AuthorId)

This query will give the following result:

             - Author A : 2 books
             - Author B : 3 books
             - Author C: 1 book

But in the Authors table, there are some authors without any books yet. For example, there two authors, Author D and Author E that have no books yet.

I want to write query that includes all authors and number of ther books, even though they don't have any book yet, no record in the Books table yet.

I want to get something like like this:

             - Author A : 2 books
             - Author B : 3 books
             - Author C: 1 book
             - Author D: 0 book
             - Author E: 0 book

Thank you.

Is there a reason for the grouping? Doesn't this work?

db.Authors.Select(a => new { Author, BookCount = a.Books.Count });

Replace Property Definitions in VB.Net Code

4 votes

In VB 2010, you can use the implied properties like C# which turns this

Private _SONo As String

Public Property SONo() As String
    Get
        Return _SONo
    End Get
    Set(ByVal value As String)
        _SONo = value
    End Set
End Property

Into

Public Property SONo() As String

What I want to do is replace the old style with the new style in a few file. Since Visual Studio's find and replace tool allows you to do regular expressions, I assume there must be an expression I can use to do this conversion.

What would the regular expression be to do this conversion?

This could be dangerous as you might have logic in the property setters/getters, but if they don't have logic you could say:

Regular Expression:

Private\s_(\w+)\sAs\s(\w+).*?(^\w+).*?Property.*?End\sProperty

Replace:

${3} Property ${1} As ${2}

I've tested this with RegexBuddy targeting the .NET regex variant. Note, that this may or may not work in the Visual Studio Find/Replace prompt as that is yet another variant.

UPDATE: VS's variant (Dot can't match newlines so we need to add that functionality, also converted: \w = :a, \s = :b, {} for tags, and *? = @):

Private:b_{:a+}:bAs:b{:a+}(.|\n)@{:a+}(.|\n)@Property(.|\n)@End:bProperty

\3 Property \1 As \2

The Regex does the following:

Options: dot matches newline; case insensitive; ^ and $ match at line breaks

Match the characters “Private” literally «Private»
Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s»
Match the character “_” literally «_»
Match the regular expression below and capture its match into backreference number 1 «(\w+)»
   Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s»
Match the characters “As” literally «As»
Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s»
Match the regular expression below and capture its match into backreference number 2 «(\w+)»
   Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match any single character «.*?»
   Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the regular expression below and capture its match into backreference number 3 «(\w+)»
   Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match any single character «.*?»
   Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the characters “Property” literally «Property»
Match any single character «.*?»
   Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the characters “End” literally «End»
Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s»
Match the characters “Property” literally «Property»

How can I implement a handler method for exceptions correctly?

4 votes

Suppose I have the following construct:

Public Sub SomeMethod()
   Try
      doSomething()
   Catch ex as Exception
      handleException(ex)
   End Try
End Sub

And I would like to write handleException(ex). Suppose my class has different options of handling events:

 Public Enum ExceptionHandlingType
        DisplayInMessageBox 'Display in msgbox
        ThrowToCaller       'Raise the error to the caller routine
        RaiseOnMessageEvent 'e-mail
    End Enum

Below is my attempt at writing "handleException". It seems no matter what I do, if the object was set with Exception mode of "ThrowToCaller" then the stack trace gets all messed up when I use handleException(). How can I just have a clean stack trace generated when the option is "ThrowToCaller" (every other option seems like it is working fine)

Public Sub handleException(ex as Exception)
  Select Case mExceptionHandling
            Case ExceptionHandlingType.DisplayInMessageBox
                MsgBox(ex.Message)
            Case ExceptionHandlingType.ThrowToCaller
                Throw New Exception(ex.Message, ex)
            Case ExceptionHandlingType.RaiseOnMessageEvent
                SendEMailMessage(ex)
        End Select
End Sub

Try changing the call to

if (!HandleException(ex)) throw;

and HandleException() to

bool HandleException(Exception ex) {
    bool handled = false;

    if (ex is SomeException) {
        ... handle the exception ...
        handled = true
    }
    return handled;
}

That should do the trick.

Which is better for performance? And vs AndAlso

4 votes

When writing an If statement, I've always used And when needed like:

If 1=1 And 2=2 Then

The only time I ever used AndAlso is if the second condition will error if the first isnt true like:

If Not IsDbNull(Value) AndAlso Value=2 Then

However, recently I've heard that AndAlso is better for performance than And as the second condition is only read when the first is true.

In this case, should I always just use AndAlso?

Yes, AndAlso can be faster than And, because it doesn't evaluate subsequent conditions if an earlier condition proves false.

And is a throwback to earlier versions of Visual Basic.
Most (I hesitate to say all) modern languages use boolean operators that short-circuit conditions that don't strictly need to be evaluated.

e.g. && the and operator for C style languages all perform as AndAlso.

Be careful if you've lots of code that use And and Or, a global search and replace can change existing behaviour, if the second condition involves a function call that has side effects.

I would prefer using AndAlso and OrElse unless you specifically require the functionality provided by And & Or

Why must an implementing property in VB.NET have matching 'ReadOnly' specifiers?

4 votes

The following works in C#:

interface I
{
    int X { get; }
}

class C : I
{
    public int X
    {
        get { ... }
        set { ... }
    }
}

The following does not work in VB.NET:

Interface I
    ReadOnly Property X As Integer
End Interface

Class C
    Implements I

    Public Property X As Integer Implements I.X
        Get
            ...
        End Get
        Set(value As Integer)
            ...
        End Set
    End Property
End Class

The error message Implementing property must have matching 'ReadOnly' or 'WriteOnly' specifiers is pretty self-explanatory, so I do know what's wrong here. It's also not a big issue, because it's quite easy to work around this limitiation.

I'm curious, though: Does anyone know why the VB designers decided to treat this case differently than in C#?

I'm not sure about the VB side, but with the explicit interface implementation of I.X in C# you'd also get a complaint about the added setter:

interface I
{
    int X { get; }
}

class C : I
{
    int I.X  // explicit implementation of I.X
    {
        get { return 1; }
        set { }
    }
}

You get a similar error in C#. For the VB, may want to check out this SO thread: If an interface defines a ReadOnly Property, how can an implementer provide the Setter to this property ?

Visual Studio / VB.Net 2008 IntelliSense Odd Behavior

4 votes

I am primarily a C# developer; however, I am currently working on a project for a client who preferred VB.net. I have managed to switch over fairly well, with one frustrating exception. When editing a C# file in Visual Studio pressing enter will select an item out of the IntelliSense window and keep the cursor at the end of the selected statement.

However, when editing a VB file, pressing enter selects the item out the IntelliSense popup AND moves the cursor to the next line. I realize that this is a small thing, but it drives me crazy, because it makes it really hard to switch between C# and VB projects.

I have searched for everything I can think of in Google and found nothing. Does anyone know of a way to change the IntelliSense selection behavior? Thanks in advance.

It just can't be done with VB.NET for now, according to this thread from Microsoft.

One reader there suggested and open source IDE called SharpDevelop to get C# behaviors on VB.NET code.

How to tell when a web page has changed by x% in VB.net?

4 votes

I'm trying to write a little utility which will check periodically and tell me if/when a web page's (could be any URL) content has changed. I've read the other postings but they don't really answer my question (as far as I can tell).

I know for static pages there is a last-modified header. However, what about dynamic pages? I got Oli's comment that storing a hash of the contents works but that's not really idea because the page might simply have a time stamp on it (the date-time that the page was produced). Clearly, in this case, the content would be different on every single request even though nothing significant has changed.

So, now I'm thinking to tie it to a percentage of 'changedness.' Something like, more than 5% changed will cause the 'changed' logic to run.

I'd love to hear any ideas on how I can reliably tell when a page has changed, in a meaningful way.

One solution is to determine the parts of a dynamic page that are static that you would consider 'changed' if they are updated. Using a diff tool (example below) to compare the original page source to updated page source. However, determining these parts manually for every instance of a page would not necessarily scale well if you have more than a few dozen pages.

Two ideas:

1) Use HTMLAgilityPack (.NET Library http://htmlagilitypack.codeplex.com/) to parse the page DOM and perform a count of distinct page elements for both the stored, previously scanned page and the recently scanned version of it. Use a formula that you deem satisfactory to flag a 'change'. A very simple example would be the old copy has 8 anchor <a> tags and the new one only has 5.

2) Use a diffing library DiffPlex http://diffplex.codeplex.com/ to determine word and line changes. You will need to come up with, through analysis, a change base line for word and line additions that would trigger a valid 'change'.

        var d = new Differ();
        var inlineBuilder = new InlineDiffBuilder(d);
        var result = inlineBuilder.BuildDiffModel(OldText, NewText);
        int inserted, deleted, modified = 0;
        foreach (var line in result.Lines)
        {

            if(line.Type == ChangeType.Inserted)
                inserted++;
            else if(line.Type == ChangeType.Deleted)
               deleted++;
            else if (line.Type == ChangeType.Modified)
                modified++;


        }
        // some base line formula/threshold you come up with through analysis
        if (deleted + inserted + modifed > 10)
           changed = true;
    }

Distinct in LINQ with anonymous types (in VB.NET)

2 votes

Supposing the referenced List below contains 2 elements:

Dim Countries = From c In List _
                Select New With { .Country = c.Country, .CountryID = c.CountryID }

the code above returns

.Country=Spain .CountryID = 1
.Country=Spain .CountryID = 1

How can i get the distinct values? The Countries query should contain only

.Country=Spain .CountryID = 1

I can only assume you're dead set on the use of anonymous type as the answer given by Alex Peck is correct. (and I've upvoted it).

However, this boils down to a VB.NET vs C# compiler discussion.

In VB.NET, when an anonymous type is encountered only those properties declared as key properties can be used for comparison purposes. So in VB.NET without key, when you're attempting to do a distinct comparison, nothing will occur.

Read all about it here.

So first, to answer your question, this works with anonymous types:

Dim Countries = From c In List Select New With {Key c.CountryId, c.Country} Distinct.ToList

enter image description here

This is why freedompeace's answer doesn't quite work.

C# however the compiler is a little different.

When an anonymous type is encountered and a comparison operation is needed the c# compiler goes all gang busters and overrides Equals and GetHashCode. It will iterate over all of the public properties of the anonymous type to compute the object's hash code to test for equality.

And you can read more about that here.

Hope this answers your question.

Stop VB from showing xml comment preview

1 votes

When you create an XML comment in C# and collapse it you only see:

<Summary>...

But in VB you could potentially see

Initializes the fubble to the watzer. This is actually the second line.

Having that line over your code can introduce lots of unwanted noise when trying to debug a class. Is there any way to turn off xml comment previews for VB?

Unchecking the Generate XML documentation file on the Compile tab for the VB.NET project should do it.

Remember to turn this back on again when you are finished if you want to have your XML comments built. However leaving this off will improve Visual Studio performance.

Is it safe to assume an Integer will always be 32 bits in VB.Net?

1 votes

Related:

Is it safe to assume an int will always be 32 bits in C#?

The linked question asks whether it is "safe to assume that an int will always be 32 bits in C#". The accepted answer states that "the C# specification rigidly defines that int is an alias for System.Int32 with exactly 32 bits".

My question is this: does this hold true for VB.Net's Integer? Is it safe to assume that Integer will always be an alias for int32?

Yes.
The Integer type will never change.

The spec (7.3 Primitive Types) says:

The integral value types Byte (1-byte unsigned integer), Short (2-byte signed integer), Integer (4-byte signed integer), and Long (8-byte signed integer). These types map to System.Byte, System.Int16, System.Int32, and System.Int64, respectively. The default value of an integral type is equivalent to the literal 0.

What does a := in vb.net do? (colon equals)

1 votes

Possible Duplicate:
What is the use of the := syntax?

I've tried hunting down the MDSN docs for := in vb.net as well as scoured google only to be linked to a dead msdn page... So im hoping someone can direct me or even tell me what the purpose of := would be.

thank you! andy

It strongly names arguments;

function foo(x As Long, y As Long)
   debug.print x, y
end Function

Called with revered but names arguments:

foo y:=999, x:=111

prints:

111, 999

WPF Data Binding and Templates

0 votes

I am working on a project and I want to have a list box with a custom data template populate with user data. My question is, when I click on an item in the list box, how can I tell what item I selected? Basically, if I select "kevin", I want to display his data. If I select Dave, I want to display his data. I do not know how to get the data our after it is bound...

EDIT: I found a really great tutorial that covers this. A very hidden gem.

http://msdn.microsoft.com/en-us/library/aa480224.aspx

Bind SelectedItem of the ComboBox to any property.

<Window x:Class="ComboBoxSelectedItemBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="500">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <ListBox   x:Name="st"
              ItemsSource="{Binding Path=Customers,Mode=TwoWay}" IsSynchronizedWithCurrentItem="True" 
              SelectedItem="{Binding Path=SelectedCustomer,Mode=TwoWay}"
               Margin="0,38,0,80">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=Name}"></TextBlock>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <TextBlock Text="{Binding Path=SelectedCustomer.Name}" Grid.Column="1" VerticalAlignment="Center" Margin="5"></TextBlock>
</Grid>

    public partial class Window1 : Window, INotifyPropertyChanged
{
    private ObservableCollection<Customer> customers;
    public ObservableCollection<Customer> Customers
    {
        get
        {
            return customers; 
        }
        set
        {
            customers = value;
            NotifyPropertyChanged("Customers");
        }
    }

    private Customer selectedCustomer;
    public Customer SelectedCustomer
    {
        get
        {
            return selectedCustomer;
        }
        set
        {
            selectedCustomer = value;
            NotifyPropertyChanged("SelectedCustomer");
        }
    }


    public Window1()
    {
        Customers = new ObservableCollection<Customer>();
        Customers.Add(new Customer() { ID = 1, Name = "Ravi", Salary = 1000 });
        Customers.Add(new Customer() { ID = 99, Name = "Alex", Salary = 3000 });
        Customers.Add(new Customer() { ID = 123, Name = "Steve", Salary = 100 });
        Customers.Add(new Customer() { ID = 31, Name = "Alice", Salary = null });
        InitializeComponent();

        DataContext = this;
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    #endregion
}

public class Customer:INotifyPropertyChanged
{
    private int id;
    public int ID
    {
        get
        {
            return id;
        }
        set
        {
            id = value;
            NotifyPropertyChanged("ID");
        }
    }

    private string name;
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
            NotifyPropertyChanged("Name");
        }
    }

    private decimal? salary;
    public decimal? Salary
    {
        get
        {
            return salary;
        }
        set
        {
            salary = value;
            NotifyPropertyChanged("Salary");
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    #endregion
}