Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uppercase a List of object with LINQ

Tags:

c#

linq

I have the code below. I'd like to convert all items in this list to uppercase.

Is there a way to do this in Linq ?

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class MyClass
{
    List<Person> myList = new List<Person>{ 
        new Person { FirstName = "Aaa", LastName = "BBB", Age = 2 },
        new Person{ FirstName = "Deé", LastName = "ève", Age = 3 }
    };
}

Update

I don't want to loop or go field by field. Is there a way by reflection to uppercase the value for each property?

like image 404
Kris-I Avatar asked Jul 30 '12 13:07

Kris-I


4 Answers

Why would you like to use LINQ?

Use List<T>.ForEach:

myList.ForEach(z =>
                {
                    z.FirstName = z.FirstName.ToUpper();
                    z.LastName = z.LastName.ToUpper();
                });

EDIT: no idea why you want to do this by reflection (I wouldn't do this personally...), but here's some code that'll uppercase all properties that return a string. Do note that it's far from being perfect, but it's a base for you in case you really want to use reflection...:

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }
}

public static class MyHelper
{
    public static void UppercaseClassFields<T>(T theInstance)
    {
        if (theInstance == null)
        {
            throw new ArgumentNullException();
        }

        foreach (var property in theInstance.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            var theValue = property.GetValue(theInstance, null);
            if (theValue is string)
            {
                property.SetValue(theInstance, ((string)theValue).ToUpper(), null);
            }
        }
    }

    public static void UppercaseClassFields<T>(IEnumerable<T> theInstance)
    {
        if (theInstance == null)
        {
            throw new ArgumentNullException();
        }

        foreach (var theItem in theInstance)
        {
            UppercaseClassFields(theItem);
        }
    }
}

public class Program
{
    private static void Main(string[] args)
    {
        List<Person> myList = new List<Person>{
            new Person { FirstName = "Aaa", LastName = "BBB", Age = 2 },
            new Person{ FirstName = "Deé", LastName = "ève", Age = 3 }
        };

        MyHelper.UppercaseClassFields<Person>(myList);

        Console.ReadLine();
    }
}
like image 159
ken2k Avatar answered Oct 19 '22 19:10

ken2k


LINQ does not provide any facilities to update underlying data. Using LINQ, you can create a new list from an existing one:

// I would say this is overkill since creates a new object instances and 
// does ToList()
var updatedItems = myList.Select(p => new Person 
                              {
                                FirstName = p.FirstName.ToUpper(), 
                                LastName = p.LastName.ToUpper(), 
                                Age = p.Age
                              })
                         .ToList();

If using LINQ is not principal, I would suggest using a foreach loop.

UPDATE:

Why you need such solution? Only one way of doing this in generic manner - reflection.

like image 37
sll Avatar answered Oct 19 '22 18:10

sll


the Easiest approach will be to use ConvertAll:

myList = myList.ConvertAll(d => d.ToUpper());

Not too much different than ForEach loops the original list whereas ConvertAll creates a new one which you need to reassign.

var people = new List<Person> { 
    new Person { FirstName = "Aaa", LastName = "BBB", Age = 2 },
    new Person{ FirstName = "Deé", LastName = "ève", Age = 3 }
};
people = people.ConvertAll(m => new Person 
         {
             FirstName = m.FirstName?.ToUpper(), 
             LastName = m.LastName?.ToUpper(), 
             Age = m.Age
         });

to answer your update

I don't want to loop or go field by field. Is there a way by reflection to uppercase the value for each property?

if you don't want to loop or go field by field. you could use property on the class to give you the Uppercase like so

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public string FirstNameUpperCase => FirstName.ToUpper();
    public string LastNameUpperCase => LastName.ToUpper();
}

or you could use back field like so

public class Person
{
    private string _firstName;
    public string FirstName {
        get => _firstName.ToUpper();
        set => _firstName = value;
    }

    private string _lastName;
    public string LastName {
        get => _lastName.ToUpper();
        set => _lastName = value;
    }

    public int Age { get; set; }
}
like image 43
Nerdroid Avatar answered Oct 19 '22 18:10

Nerdroid


You can only really use linq to provide a list of new objects

var upperList = myList.Select(p=> new Person {
   FirstName = (p.FirstName == null) ? null : p.FirstName.ToUpper(),
   LastName = (p.LastName == null) ? null : p.LastName.ToUpper(),
   Age = p.Age
   }).ToList();
like image 30
Bob Vale Avatar answered Oct 19 '22 18:10

Bob Vale