代码之家  ›  专栏  ›  技术社区  ›  Sinnombre

如何检查列表是否包含与调用者类型相同的对象

c#
  •  -1
  • Sinnombre  · 技术社区  · 1 年前

    我有一个具有相同基类的对象列表。这些对象可以从多个位置构造,但只能作为此类列表的一部分存在。添加新对象时,我想检查同一类的对象是否已在其父列表中。我试着这样做:

    public class ListHolder
    {
      List<BaseType> a = new List<BaseType>();
    }
    
    public abstract class BaseType
    {
      public BaseType(ListHolder listIn)
      {
        if (listIn.a.OfType<typeof(this)>().Any())
        {
          listIn.a.OfType<typeof(this)>().ToList()[0].Reapply();
        } else {
          listIn.Add(this);
          Apply();
        }
      }
      
      protected abstract void Reapply();
      protected abstract void Apply();
    }
    

    这行不通;我得到了一系列语法错误,我猜是因为OfType不喜欢在它的调用中计算typeof。说Type t=typeof(this)然后调用OfType<t>。我怎样才能绕过这个问题?

    编辑: 我希望随后能够拨打类似的电话

    public class DerivedType : BaseType
    {
      protected override void Reapply() {}
      protected override void Apply() {}
    }
    
    ListHolder b = new ListHolder();
    b.a.Add((BaseType)Activator.CreateInstance(DerivedType)); // Should call Apply
    b.a.Add((BaseType)Activator.CreateInstance(DerivedType)); // Should call Reapply
    

    o在本例中,等待添加到列表是在构造函数中。。。好吧,你明白要点了

    2 回复  |  直到 1 年前
        1
  •  1
  •   ipodtouch0218    1 年前

    而不是使用 OfType<T>() ,它接受一个泛型参数(在 编译时间 ),您可以检查是否有任何元素与 this.GetType() (这是在 运行时间 ),因为 这个。GetType() 指子类的类型,而不是父类的类型:

    public abstract class BaseType
    {
      public BaseType(ListHolder listIn)
      {
        // Find the first element of the (child's) type
        var element = listIn.a.FirstOrDefault(element => element.GetType() == this.GetType());
          
        if (element != null)
        {
          element.Reapply();
        }
        else
        {
          listIn.a.Add(this);
          Apply();
        }
      }
    
      protected abstract void Reapply();
      protected abstract void Apply();
    }
    

    两个儿童班测试 A B :

    public class A : BaseType
    {
        public A(ListHolder listIn) : base(listIn) { }
        protected override void Reapply()
        {
            Console.WriteLine("A reapply");
        } 
        protected override void Apply()
        {
            Console.WriteLine("A apply");
        }
    }
    
    public class B : BaseType
    {
        public B(ListHolder listIn) : base(listIn) { }
        protected override void Reapply()
        {
            Console.WriteLine("B reapply");
        } 
        protected override void Apply()
        {
            Console.WriteLine("B apply");
        }
    }
    
    public static void Main()
    {
        ListHolder holder = new();
        
        new A(holder);
        new B(holder);
        new B(holder);
        new A(holder);
    }
    

    结果为:

    A apply
    B apply
    B reapply
    A reapply
    
        2
  •  -3
  •   Ibram Reda    1 年前
    public class ListHolder
    {
        public List<BaseType> a = []; // make it public and intialize it
    }
    
    public abstract class BaseType
    {
        public BaseType(ListHolder listIn)
        {
            var t = listIn.a.FirstOrDefault(i => i is BaseType); // get the first element of the base type or 
                                                                 // it will return null if not exist such element
            if (t is not null)
            {
                t.Reapply();
            }
            else
            {
                listIn.a.Add(this);
                Apply();
            }
        }
    
        protected abstract void Reapply();
        protected abstract void Apply();
    }