I am trying to do something like this:

public Boolean CheckLogin(String accNumber, String pin)
        {
            String checkAccNumber;
            String checkPin;
            String line;
            String[] splitedLine;

            StreamReader sr = new StreamReader(FILE);

            while (line = sr.ReadLine())
            {
                splitedLine = line.Split(' ');

                checkAccNumber = splitedLine[0];
                checkPin = splitedLine[1];

                if ((checkAccNumber == accNumber) && (checkPin == pin))
                    return true;
            }
            return false;
        }

It is supose to keep on reading lines in the file to see if there is a line that matches the users pin and account number. The pin and account number is in one line so it will have to break that line into peaces of each word.

But my problem is it gives an error. It says that i cannot convert 'line' to a 'Boolean'.

So how do I go about this then?

Recommended Answers

All 10 Replies

Your while condition is wrong. It should be while ((line = sr.ReadLine()) != null)

A while loop condition expects a boolean, not an assignment.
You probably got the error message: Cannot implicitly convert type 'string' to 'bool'

Rather than a while loop a foreach might work better. Something like this:

    using System.IO;

        public Boolean CheckLogin(String accNumber, String pin)
        {
            String checkAccNumber;
            String checkPin;
            String[] splitedLine;
            foreach (string line in File.ReadAllLines(FILE))
            {
                splitedLine = line.Split(' ');
                checkAccNumber = splitedLine[0];
                checkPin = splitedLine[1];
                if ((checkAccNumber == accNumber) && (checkPin == pin))
                    return true; 
            }

            return false;
        }

As far as I know foreach loops are always slower than while/for. Although the syntax looks clearer, I don't know if there are any other advantages to what he needs.

The overhead to create the iterator is slower in foreach than for, but imperceptibly so. A lot of the time it depends on the type of collection you use as well. When you're using a loop, the work you do inside the loop will affect performance of the loop far more than the statement to create it.

In general, foreach conveys intention far better than for and so I favour foreach unless an iterative index variable is expressly required (at which point I'd review the design of my app...)

The compiler will attempt to optimise things like this for you and generally it does so extremely well. Unless your loops are taking minutes to execute and you've already optimised the working code (the code inside your loop) as best you can, you can then see if a for loop would actually be quicker. In some cases a for loop may actually be slower, depending on the work you perform inside the loop.

In this case, the foreach loop requires a ReadAllLines instead of a line by line read. So unless you need the whole file in memory at once there is no reason not to use while. Besides, the StreamReader uses lazy evaluation which increases performance... so they say

Deferred execution isn't an increase in performance really, in fact it can be quite the opposite when used incorrectly. All deferred execution does is wait until you need the data before executing the statement. The same code is run, just not necessarily where you asked it to.

I agree with your other point though; doing a full file read into memory is a bad idea. For a start this only supports 4Gb files on 32Bit and it will take a long time to run on large files. A while loop is much more suitable in this instance.

Deferred execution might not make a difference in smaller tasks. The point of lazy execution is to not retrieve the data unless you need it. For example in a linq expression against a table:

var a = customers.Where(Active).(c => c.Name);

Lazy execution would not load the whole table into memory, but instead take the next customer when MoveNext() is called on the IEnumerator. And as far as I know that would mean the GarbageColletor would be called fewer times.

You might be right also, that when used incorrectly it could result in a decrease in performance.

Deferred execution, especially on IEnumerable and LINQ will perform the query every time you access it.

For example;

public IEnumerable<Int32> GetIndexesAbove(Int32 indexValue)
{
    return _myList.Where(item => item > indexValue);
}

public void SomeMethod()
{
    var indexes = GetIndexesAbove(10);

    // GetIndexesAbove called here
    Boolean anyIndexes = indexes.Any();

    // GetIndexesAbove called again here
    Int32 indexCount = indexes.Count();

    // GetIndexesAbove called again here...
    var tenIndex = indexes.SingleOfDefault(item => item == 10);
}

This can be negated by executing it into a strongly typed class, however, this means losing the "benefit" of deferred execution:

public IEnumerable<Int32> GetIndexesAbove(Int32 indexValue)
{
    return _myList.Where(item => item > indexValue);
}

public void SomeMethod()
{
    // GetIndexesAbove called here
    List<Int32> indexes = GetIndexesAbove(10).ToList();

    Boolean anyIndexes = indexes.Any();
    Int32 indexCount = indexes.Count();
    var tenIndex = indexes.SingleOfDefault(item => item == 10);
}

I understand the point of deferred execution, it's useful especially in events and threading. But it's not magic. The performance gain is 0 if you actually make the call and negative if you use it like I have in the first example.

The garbage collector also doesn't work like that. It's a scheduled process so it makes a sweep and does everything at once, unlike C++ where your destructor is run immediately.
If you start fragmenting heavily and building up and tearing down small objects repeatedly then yes, it will be called more often :)

Same with Enumerator; at the point you call MoveNext, it has been executed. It doesn't do any magic streaming that wouldn't normally occur without deferred execution.

Take the Microsoft code for example; all your iterator does is move the index + 1 and then return that object. Therefor, the entire dataset must be in memory anyway (unless you do streaming, which is different to deferred execution) :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.