none
Předání seznamu (List<T>) vlastní napsané metodě

    Dotaz

  • Ahoj, rád bych se zeptal na:

    Mám několik seznamů (List), každý má jiný datový typ (obsahují vlastní objekty, přičemž každý objekt má vlastnost jestli je aktivní nebo ne (bool active)).

    Rád bych proto napsal vlastní flexibilní metodu, která by projela takový seznam a vymazala by z něj neaktivní položky.

    Jakým způsobem mám předávat respektive napsat metodu, tak aby byla schopna brát seznam s jakýmkoli datovým typem? Dá se v tomhle případě použít nový dat. typ dynamic? něco jako:

    void ClearList (List<dynamic> AktualniList)

    {

    ...

    }

     

    vím, že tohle je špatně, ale na ukázku, aby byla moje myšlenka pochopitelná.

    Díky moc

    pondělí 10. května 2010 9:21

Odpovědi

  • Udělat to jde, jen to chce například tu bool vlastnost schovat do Interface, ten implementovat všem třídám které do List<T> vkládáte a pak už nic nebrání vytvořit v nějaké třídě takovouto metodu:

       public static List<T> Akce<T>(List<T> list) where T : IAlfa

       {

           return list.Where(alfa => alfa.Info).ToList();

       }

     

        public interface IAlfa

        {

            bool Info { get; set; }

        }

    Tato metoda vrátí nový seznam bez vypnutých prvků. Metoda Akce je samozřejmě schovaná v nějaké pomocné třídě.

    pondělí 10. května 2010 18:59
  • Ahoj, Tomův příspěvek je asi nejlepší, pokud chceš využít typovou kontrolu. Pokud ale trváš na použití dynamic, je to taky možné. Problém je v tom, že standardní chování DLR funguje tak, že pokud field/metoda/property v objektu není, DLR vyhodí výjimku.

    V .NET 4 ale existuje typ DynamicObject ze kterého pokud zdědíš svůj objekt, můžeš přepsat jakým způsobem bude DLR získávat informace o memberech a tím pádem nahradit padání při neexistujícím memberu za vrácení třeba null.

    Příklad:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.CompilerServices;
    using Microsoft.CSharp.RuntimeBinder;
    using System.Dynamic;
    using System.Reflection;
    
    namespace ListRemove
    {
      class Program
      {
        class Product1 { public int id; public bool active; }
        class Product2 { public int id; public bool active2; }
    
        static void Main(string[] args)
        {
          var listOne = new List<Product1>(
            new[] { new Product1 { id = 1, active = true }, new Product1 { id = 2, active = false } }
            );
          var listTwo = new List<Product2>(
            new[] { new Product2 { id = 3, active2 = true }, new Product2 { id = 4, active2 = false } }
            );
    
          PrintList(listOne);
          PrintList(listTwo);
    
          Console.ReadLine();
    
        }
    
        private static void PrintList(dynamic anyList)
        {
          foreach (dynamic listItem in anyList)
          {
            dynamic dynamicObjectItem = new MembersDynamicWrapper(listItem);
    
            bool? active = dynamicObjectItem.active;
            bool? active2 = dynamicObjectItem.active2;
    
            bool anyActive = active.GetValueOrDefault() || active2.GetValueOrDefault();
    
            if (anyActive)
              Console.WriteLine(string.Format("Item (id: {1}) contains any of (active, active2) fields set to true. ", listItem , listItem.id));
          }
        }
      }
    
      public class MembersDynamicWrapper : DynamicObject
      {
        private object _object;
        public MembersDynamicWrapper(object _object) { this._object = _object; }
    
        // Handle getting the nonexisting fields as null
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
          FieldInfo prop = _object.GetType().GetField(binder.Name);//(binder.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetField);
          if (prop == null)
          {
            result = null;
            return true;
          }
    
          result = prop.GetValue(_object);
          return true;
        }
    
      }
    }
    

    M
    pátek 25. června 2010 22:27

Všechny reakce

  • Udělat to jde, jen to chce například tu bool vlastnost schovat do Interface, ten implementovat všem třídám které do List<T> vkládáte a pak už nic nebrání vytvořit v nějaké třídě takovouto metodu:

       public static List<T> Akce<T>(List<T> list) where T : IAlfa

       {

           return list.Where(alfa => alfa.Info).ToList();

       }

     

        public interface IAlfa

        {

            bool Info { get; set; }

        }

    Tato metoda vrátí nový seznam bez vypnutých prvků. Metoda Akce je samozřejmě schovaná v nějaké pomocné třídě.

    pondělí 10. května 2010 18:59
  • Ahoj, Tomův příspěvek je asi nejlepší, pokud chceš využít typovou kontrolu. Pokud ale trváš na použití dynamic, je to taky možné. Problém je v tom, že standardní chování DLR funguje tak, že pokud field/metoda/property v objektu není, DLR vyhodí výjimku.

    V .NET 4 ale existuje typ DynamicObject ze kterého pokud zdědíš svůj objekt, můžeš přepsat jakým způsobem bude DLR získávat informace o memberech a tím pádem nahradit padání při neexistujícím memberu za vrácení třeba null.

    Příklad:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.CompilerServices;
    using Microsoft.CSharp.RuntimeBinder;
    using System.Dynamic;
    using System.Reflection;
    
    namespace ListRemove
    {
      class Program
      {
        class Product1 { public int id; public bool active; }
        class Product2 { public int id; public bool active2; }
    
        static void Main(string[] args)
        {
          var listOne = new List<Product1>(
            new[] { new Product1 { id = 1, active = true }, new Product1 { id = 2, active = false } }
            );
          var listTwo = new List<Product2>(
            new[] { new Product2 { id = 3, active2 = true }, new Product2 { id = 4, active2 = false } }
            );
    
          PrintList(listOne);
          PrintList(listTwo);
    
          Console.ReadLine();
    
        }
    
        private static void PrintList(dynamic anyList)
        {
          foreach (dynamic listItem in anyList)
          {
            dynamic dynamicObjectItem = new MembersDynamicWrapper(listItem);
    
            bool? active = dynamicObjectItem.active;
            bool? active2 = dynamicObjectItem.active2;
    
            bool anyActive = active.GetValueOrDefault() || active2.GetValueOrDefault();
    
            if (anyActive)
              Console.WriteLine(string.Format("Item (id: {1}) contains any of (active, active2) fields set to true. ", listItem , listItem.id));
          }
        }
      }
    
      public class MembersDynamicWrapper : DynamicObject
      {
        private object _object;
        public MembersDynamicWrapper(object _object) { this._object = _object; }
    
        // Handle getting the nonexisting fields as null
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
          FieldInfo prop = _object.GetType().GetField(binder.Name);//(binder.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetField);
          if (prop == null)
          {
            result = null;
            return true;
          }
    
          result = prop.GetValue(_object);
          return true;
        }
    
      }
    }
    

    M
    pátek 25. června 2010 22:27