0

I have this query:

int cid =  (from c in dc.Cs
                where c.id == cid
                select c.clientid).FirstOrDefault();

return cid;

where c.clientid is nullable. But I receive this error:

Cannot implicitly convert type 'int?' to 'int'. An explicit conversion exists (are you missing a cast?)

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
alxem
  • 215
  • 4
  • 12
  • 2
    What do you expect the value of `cid` to be if either `c.clientid` is `null` in the first match, or if there are no matches? – Jon Skeet Oct 18 '17 at 14:37
  • `... .FirstOrDefault().Value;` – Dmitry Bychenko Oct 18 '17 at 14:37
  • @DmitryBychenko thx that worked – alxem Oct 18 '17 at 14:38
  • 1
    You should read [what's the difference between 'int?' and 'int' in C#](https://stackoverflow.com/questions/121680/whats-the-difference-between-int-and-int-in-c) – Samir Aguiar Oct 18 '17 at 14:38
  • 3
    @alxem No, it just turned a compiler error into a runtime error without actually fixing the problem. – Servy Oct 18 '17 at 14:38
  • Bear in mind that `FirstOrDefault` can be `null` in which case `.Value` will fault. You should employ proper error checking prior to obtaining a value. –  Oct 18 '17 at 14:39
  • 1
    Why use an `int` in the first place, if you clearly should use a `Nullable`? – Zohar Peled Oct 18 '17 at 14:39
  • @alxem it will throw an Exception if the query returns no items. But if you know for sure that situation will *never* happen, then use `.First();` instead of `FirstOrDefault().Value;` (functionally equivalent and obviously shorter code). – Peter B Oct 18 '17 at 14:39
  • @Polyfun If `clientid` was an `int` then the OP wouldn't be getting this error. Since they're getting this error, it must be an `int?`. – Servy Oct 18 '17 at 14:46

1 Answers1

6

Well, int? can be null while int can't. That's why the compiler complains: what should it assign to cid when the query returns null. You can try providing some default value in case of null:

int cid = (  from c in dc.Cs
            where c.id == cid
           select c.clientid)
  .FirstOrDefault() ?? 0; //TODO: put the right default value instead of 0

return cid;

which means return 0 in case of null (please, notice that you have two possibilities: 1. 1st item c.clientid is null; 2. dc.Cs when filtered is empty) and int?.Value otherwise

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • 1
    @Samir Aguiar: sorry, but in case of *empty* `.FirstOrDefault()` returns `null` and, finally the *single* default value. In your syntax we have *two* defaults: when 1st value is null and when `IEnumerable` is empty. It's a problem when default is `0`, but it is when it is, say `-1` – Dmitry Bychenko Oct 18 '17 at 14:48