简体   繁体   中英

How can get Property and the Value in a generic Class?

Here is where is call the function and create the object Maybe this way you can see what I'm trying to do

     class Program 
        {

            static void Main(string[] args)
            {

                 //here I create an object and pass the type Person
                var Crud = new Crud<Person>();
                //here I invoke the method Create and pass the object "Person"
                Crud.Create(new Person(Crud.Id) { Name = "Sameone", Age = 24 });
//here I invoke the method again to Create and pass an other object "Person"
                    Crud.Create(new Person(Crud.Id) { Name = "Sameone2", Age = 24 });

               With this method Read() I get the List created back
                var Lista = Crud.Read();
                Lista.ForEach((x) => Console.WriteLine("{0}  {1}",x.Id.ToString(), x.Name));

              /* Here is where my problem starts I'm sending an new object that will replace the object with Id =1 passed by constructor   */
                Crud.Update(new Person(1) { Name = "someone3", Age = 20 });




                Console.ReadKey();
            }
}

This is where I'm trying to do using this class

//This class is a generic where T is the type "Person" that was passed

   public class Crud <T>: ICrud <T> {

      private List <T> List = new List <T> ();

      public MessageError Update(T object) {
    //Here it doesn't work its impossible to get the Id property sense its an generic object at this point
       List.RemoveAll(x => x.Id == t.Id);
       List.Add(t);
       return new MessageError {
        Status = Status.Sucessful
       };
      }
     }

My concrete type using in my code

 public class Person
    {
        public int Id { get; private set; }
        public string Name { get; set; }
        public int Age { get; set; }
        //Here I set the id for each object
        public Person(int _id)
        {
            Id = _id;
        }
    }

Here you can see the interface

 interface ICrud<T>
    {
        MessageError Create(T t);
        List<T> Read();
        MessageError Update(T t);
        MessageError Delete(int Id);
    }

I try now use like but still dont work

 List.RemoveAll(x => x.GetProperty("Id") == t.GetProperty("Id"));

I guess that is the solution for it

public MessageError Update(T t)
    {
        var type = t.GetType();

        PropertyInfo prop = type.GetProperty("Id");

        var value = prop.GetValue(t);    
        List.RemoveAll(x => x.GetType().GetProperty("Id").GetValue(x) == value);
        List.Add(t);
        return new MessageError
        {
            Status = Status.Sucessful
        };
    }

I think maybe you're simply missing a step. CRUD stands for Create, Read, Update, Delete. Here, you're creating a couple of bits of data, reading everything in, but then trying to send an Update directly to the data store. What you should do, is read in your Persons, change one or more of their properties, then Crud.Update(person) , which in turn will know that the person needs Updating rather than Creating in the data store.

In fact, it's fairly normal practice to differentiate between Create and Update based on whether the entity has a value for it's ID or not. In which case, your code might look like this:

class Program 
{
    static void Main(string[] args)
    {
        TestClass testClass = new TestClass();
        testClass.Create();

        var crud = new Crud<Person>();

        // Note we're not specifying an ID for *new* entities, the Crud class needs to assign it upon saving
        crud.Create(new Person() { Name = "Someone", Age = 24 });
        crud.Create(new Person() { Name = "Someone2", Age = 24 });

        var list = crud.ReadAll();
        list.ForEach(x => Console.WriteLine("{0} {1}", x.Id, x.Name));

        var person1 = list.Single(x => x.Id == 1);
        person1.Name = "Someone3";
        person1.Age = 20;

        Crud.Update(person1);

        Console.ReadKey();
    }
}

Although there is a further optimisation to be made here. This will load all objects from the data store into the memory of the application, which will then go through each one until it finds the one it wants. It would be better if the data store being used could do that for you. In which case you'd be able to do something more like var person1 = crud.FindById(1) . There are loads of other techniques for this, but I don't want to complicate this answer any further.

public MessageError Update(T t)
    {
/* I used this why to the the property in my last version I get the name of property by Parameter */
        var type = t.GetType();
        PropertyInfo prop = type.GetProperty("Id");

        var value = prop.GetValue(t);    
        List.RemoveAll(x => x.GetType().GetProperty("Id").GetValue(x) == value);
        List.Add(t);
        return new MessageError
        {
            Status = Status.Sucessful
        };
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM