Anup
Anup

Reputation: 9738

Implicitly typed local variables must be initialised

I want to dynamically put a condition like this :-

var data;
if(employeId != 0) {
 data = (from a in ctx.tblTO1
             join b in ctx.tblTO2
                    on a.Company equals b.Company
                    where a.Id == b.Id &&
                    a.employeeId == employeeId
                    select new { a = a, b = b }).ToList();
}else{
     data = (from a in ctx.tblTO1
                 join b in ctx.tblTO2
                        on a.Company equals b.Company
                        where a.Id == b.Id &&
                        a.Cat == cats
                        select new { a = a, b = b }).ToList();
}

The result of the above expression is of Anonymous Type. So i am not able to declare it & the 1st line gives error. Implicitly typed local variables must be initialised.

What is the way to solve this? Can we use a separate function, but then what will be the functions return type?

Upvotes: 2

Views: 226

Answers (7)

Priyank Sheth
Priyank Sheth

Reputation: 2362

Instead of var keyword you can use dynamic keyword. You can find more information on official MSDN site below:

Dynamic Type C#

Some snippets from page:

Visual C# 2010 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation.

This is an alternative of var keyword. But I think you can do without dynamic by having condition in where clause as other answer mentioned on this page.

 .Where(a=> (a.EmployeeId != 0 && a.EmployeeId == employeeId) || your other conditions)

Upvotes: 0

Jon Hanna
Jon Hanna

Reputation: 113222

Well, of course var data; makes no sense.

You could define a type with the appropriate fields to be the element type. This is particularly useful if the same type comes up more than once.

You could also use ?: where you here use if…else:

var data = (employeeId != 0)
  ? (from a in ctx.tblTO1
     join b in ctx.tblTO2
      on a.Company equals b.Company
      where a.Id == b.Id &&
        a.employeeId == employeeId
        select new { a = a, b = b }).ToList()
  : (from a in ctx.tblTO1
     join b in ctx.tblTO2
       on a.Company equals b.Company
       where a.Id == b.Id &&
         a.Cat == cats
         select new { a = a, b = b }).ToList();

But perhaps the clearest is to modify a query for just what differs with each case:

var query = from a in ctx.tblTO1
            join b in ctx.tblTO2
            on a.Company equals b.Company
            where a.Id == b.Id
            select new { a = a, b = b };

if (employeeId != 0)
  query = query.Where(i => i.a.employeeId == employeeId);
else
   query = query.Where(i => i.a.Cat == cats);
var data = query.ToList();

This has the advantage of making the difference between the two cases clearer in the code. Separating out the ToList() also has the advantage of making it clearer if you change your code in such a way as to no longer need it.

Upvotes: 6

Kędrzu
Kędrzu

Reputation: 2425

You cannot only declare a variable implicitely, without giving it any value. When you write:

var a = "foo";

that means, that you have a variable of type string, not just a variable that you gave a value of string. Compiler need to know what the type exactly is, even if the type is implied from the usage.

When you write only declaration var a, compiler does not know what to do with it. Is it an object? Maybe string? A number? How many memory to allocate on stack?

With a staticly typed language as C# if you declare a variable, state a type. You can do it like this:

object data;
// rest of your code

Upvotes: 0

user743382
user743382

Reputation:

var data; cannot possibly work, as var is only ever resolved against the initialiser, not any subsequent assignments.

You have two major options: either you can stop using anonymous types, or you can make sure you have an initialiser. The first of these can look like:

class MyClass {
    public T01 a;
    public T02 b;
}

Now, you can use List<MyClass>.

The second of these can be broken down into two sub-options: you can either re-work your existing logic to fit in a single expression, or use a dummy value for initialisation.

The first of these can look like var data = condition ? query1 : query2;.

The second of these can look like var data = true ? null : query1;, where query1 never actually gets evaluated, it's just used to determine the type of data.

Upvotes: 0

migajek
migajek

Reputation: 8614

You could rewrite the query as follows

(from a in ctx.tblTO1
         join b in ctx.tblTO2
                on a.Company equals b.Company
                where a.Id == b.Id &&
                ( (employeId != 0 && a.employeeId == employeeId) || (a.Cat == cats))
                select new { a = a, b = b }).ToList();

Upvotes: 0

MikkaRin
MikkaRin

Reputation: 3084

var data = (from a in ctx.tblTO1
                 join b in ctx.tblTO2
                        on a.Company equals b.Company
                        where a.Id == b.Id &&
                        ((a.Cat == cats && employeId==0)||
                         (a.employeeId == employeeId))
                        select new { a = a, b = b }).ToList();

Upvotes: 0

usr
usr

Reputation: 171178

You can use a DTO class instead of the anonymous type. Resharper can make that transformation for you. Or, you can use the conditional operator to allow type inference to work here:

var data = employeId != 0 ? (query1) : (query2);

That's not going to be pretty.

There's another hack for this:

var data = new [] { new { a = 0, b = 0 } }.ToList();

This creates a dummy object to make var type inference work. You probably should not do this...

Upvotes: 3

Related Questions