Syntax Error
Syntax Error

Reputation: 1640

Linq query doesn't return a result from object within another object

I am trying to use Linq to return a property of an object within an object. This is a simplified version of the program that demonstrates the behaviour.

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp2
{
    class Program
    {
        public class Associate
        {
            public string AssocType { get; set; }
            public Contact contact { get; set; }
            public Associate(string assocType)
            {
                AssocType = assocType;
                //contact = new Contact("Contact 1", 1234);
                //contact2 = new Contact("Contact 2", 23456);
            }
        }
        public class Contact
        {
            string v1;
            int v2;
            public Contact(string v1, int v2) { this.v1 = v1; this.v2 = v2; }
            public string Name { get; set; }
            public int ID { get; set; }
        }

        static void Main(string[] args)
        {
            Associate assoc1 = new Associate("Type1");
            assoc1.contact = new Contact("Contact 1", 9876);
            Associate assoc2 = new Associate("Type2");
            assoc2.contact = new Contact("Contact 2", 1234);
            List<Associate> aList = new List<Associate>
            {
                assoc1,assoc2
            };
            var contactname = aList
                .Where(s => s.AssocType == "Type1")
                .Select(s => s.contact.Name)
                .FirstOrDefault();
            Console.Write(contactname);
            Console.Read();

        }
    }
}

The contactname variable is coming up as null but should return Contact 1 as a string. I have checked in the debugger and all the objects are set correctly and have the appropriate values. What am I doing wrong?

I also tried the below linq syntax (in place of the var contact name = aList... part but I don't think it's correct as it won't compile due to Type inference failed.

        var name = from Associate in aList
                   from Contact in Associate
                   where Associate.AssocType == "Type1"
                   select Contact.Name;

Upvotes: 2

Views: 262

Answers (2)

Ousmane D.
Ousmane D.

Reputation: 56453

In your Contact class, you're never setting the Name property so when you execute the below pipeline:

var contactname = aList.Where(s => s.AssocType == "Type1")
                       .Select(s => s.contact.Name)
                       .FirstOrDefault();

it's returning null (not to be confused with the null returned by FirstOrDefault, this is the null value of the Name property as it's never been set ).

You can prove this with:

var count = aList.Count(s => s.AssocType == "Type1" && s.contact.Name == null);
Console.Write(count); // prints  --> 1

So either, you meant:

var contactname = aList.Where(s => s.AssocType == "Type1")
                       .Select(s => s.contact.v1) // note the change
                       .FirstOrDefault();

assuming v1 is public.

or you'll explicitly need to populate the Name property of the Contact object sometime before the above pipeline.


Finally, for completeness if you want the query syntax then do:

var result = (from a in aList
              where a.AssocType == "Type1"
              select a.contact.Name)
             .FirstOrDefault();

Upvotes: 3

Nikhil Vartak
Nikhil Vartak

Reputation: 5127

Contact name is null because you have not initialised anywhere.

public Contact(string v1, int v2) { this.v1 = v1; this.v2 = v2; }

Either this should be

public Contact(string v1, int v2) { Name = v1; ID = v2; }

Or

public string Name { get; set; }

This should be (same for ID too)

public string Name { get { return v1; } }

Upvotes: 0

Related Questions