ProgrammingRookie
ProgrammingRookie

Reputation: 191

See if something is of type class

I am trying to check to see if something is a certain type of class in c#. It prints out certain labels on a form depending on what class it is a type of. This is what I have so far and it works for the "if" statement. However, I get an error of "unable to cast object of type". Is it possible to use an if-else statement in this scenario?

public void ShowStaffData(string pName)
{
  //Gets Staff Details from the name slected int he list box in the form
  people.CreatePeople();
  var currentPerson = 
    people.person.Where(p => p.Forename + " " + p.Surname == pName);

  // How the info is printed out if person selected in 
  // a member of Accademic Staff
  AccademicStaff accademic = currentPerson as AccademicStaff;

  if (currentPerson!=null)
  {
    foreach (AccademicStaff accStaff in currentPerson)
    {
      label9.Text = accStaff.Forename + " " + accStaff.Surname;
      label10.Text = accStaff.IdentificationNumber.ToString();
      label11.Text = accStaff.DateOfBirth;
      label12.Text = accStaff.Address;
      label13.Text = accStaff.Office;
      label14.Text = accStaff.School;
      label15.Text = accStaff.ModuleLeaderOf;
      label16.Text = accStaff.ProgramLeaderOf;
    }
  }      
  else
  {
    // How the info is printed out if person selected in 
    // a member of Admin Staff

    foreach (AdminStaff admin in currentPerson)
    {
      label9.Text = admin.Forename + " " + admin.Surname;
      label10.Text = admin.IdentificationNumber.ToString();
      label11.Text = admin.DateOfBirth;
      label12.Text = admin.Address;
      label13.Text = admin.Office;
      label6.Text = "Job Role";
      label14.Text = admin.JobRole;
      label7.Dispose();
      label8.Dispose();
      label15.Dispose();
      label16.Dispose();
    }
  }
}

Upvotes: 0

Views: 137

Answers (4)

Chris
Chris

Reputation: 3162

It looks like currentPerson is a single entity not a collection. so Single or FirstOrDefault would work just as well; ( Depending on if the currentPerson is unique or not ) then to test for the type I prefer using is as it handles a null check. So that if none of your labels get populated it means the person returned from the linq statement is of neither type.

    people.CreatePeople();
    var currentPerson = people.person.Where(p => p.Forename + " " + p.Surname == pName).Single();

        if(currentPerson is AcademicStaff)
        {
            label9.Text = accStaff.Forename + " " + accStaff.Surname;
            label10.Text = accStaff.IdentificationNumber.ToString();
            label11.Text = accStaff.DateOfBirth;
            label12.Text = accStaff.Address;
            label13.Text = accStaff.Office;
            label14.Text = accStaff.School;
            label15.Text = accStaff.ModuleLeaderOf;
            label16.Text = accStaff.ProgramLeaderOf;
        }
        else if(currentPerson is AdminStaff)
        {
            label9.Text = admin.Forename + " " + admin.Surname;
            label10.Text = admin.IdentificationNumber.ToString();
            label11.Text = admin.DateOfBirth;
            label12.Text = admin.Address;
            label13.Text = admin.Office;
            label6.Text = "Job Role";
            label14.Text = admin.JobRole;
            label7.Dispose();
            label8.Dispose();
            label15.Dispose();
            label16.Dispose();
        }

Upvotes: 0

w5l
w5l

Reputation: 5766

Move the if ... else ... bit into the foreach loop, since your where selector is returning a collection, not a single person.

var currentPerson = people.person.Where(p => p.Forename + " " + p.Surname == pName);

foreach (var person in currentPerson)
{

    AccademicStaff accStaff = person as AccademicStaff;
    if (accStaff != null)
    {
        label9.Text = accStaff.Forename + " " + accStaff.Surname;
        label10.Text = accStaff.IdentificationNumber.ToString();
        label11.Text = accStaff.DateOfBirth;
        label12.Text = accStaff.Address;
        label13.Text = accStaff.Office;
        label14.Text = accStaff.School;
        label15.Text = accStaff.ModuleLeaderOf;
        label16.Text = accStaff.ProgramLeaderOf;
    }
    else
    {
        // How the info is printed out if person selected in a member of Admin Staff
        label9.Text = person.Forename + " " + person.Surname;
        label10.Text = person.IdentificationNumber.ToString();
        label11.Text = person.DateOfBirth;
        label12.Text = person.Address;
        label13.Text = person.Office;
        label6.Text = "Job Role";
        label14.Text = person.JobRole;
    }       
}

I removed the calls to Dispose() on the labels, they make no sense.

Edit You could probably shorten it a bit like this:

var currentPerson = people.person.Where(p => p.Forename + " " + p.Surname == pName);

foreach (var person in currentPerson)
{

    label9.Text = person.Forename + " " + person.Surname;
    label10.Text = person.IdentificationNumber.ToString();
    label11.Text = person.DateOfBirth;
    label12.Text = person.Address;
    label13.Text = person.Office;

    AccademicStaff accStaff = person as AccademicStaff;
    if (accStaff != null)
    {
        label14.Text = accStaff.School;
        label15.Text = accStaff.ModuleLeaderOf;
        label16.Text = accStaff.ProgramLeaderOf;
    }
    else
    {
        label6.Text = "Job Role";
        label14.Text = person.JobRole;
    }       
}

Upvotes: 2

Guffa
Guffa

Reputation: 700800

First, currentPersion is a collection of items. Use the Single method to make it a single item:

var currentPerson =
  people.person.Where(p => p.Forename + " " + p.Surname == pName).Single();

(If it's possible that you don't get a match at all, you would use SingleOrDefault and then check if currentPersion is null.)

Second, after trying to cast you are checking the currentPerson variable instead of the accademic variable:

AccademicStaff accademic = currentPerson as AccademicStaff;
if (accademic != null)

Now you don't need the loops either. Use the accademic variable in the first section, and cast the reference to AdminStaff in the second:

AdminStaff admin = currentPerson as AdminStaff;

Upvotes: 7

Clint
Clint

Reputation: 6220

if (instance.GetType().IsClass)
{

}

Should do the trick.

But you shouldn't really be doing it this way, if you need different classes to print out different things then I'd recommend going down the route of creating an interface and implementing it separately on each type.

Upvotes: 0

Related Questions