从列表中删除项目的通用方法 [英] Generic method to remove items from list

查看:109
本文介绍了从列表中删除项目的通用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我有查询,如果你能帮助我,我会非常感激。

我有列表< customer> ,其属性名称为 SNO



我写了一个代码

 Public Void delete(List< Customer> dataList,String MatchedSno)
{
if(!String.IsNullOrEmpty(MatchedSno))
dataList.RemoveAll(a => a.SNO == Convert.ToInt32(MatchedSno));
else
dataList.RemoveRange(1,dataList.Count-1);

}





但我想用List of Type< t>创建一个通用方法现在想实现相同的意义

 Public Void delete< T>(List< T> dataList,String MatchedSno)
{
if (!String.IsNullOrEmpty(MatchedSno))
dataList.RemoveAll(a => a.SNO == Convert.ToInt32(MatchedSno));
else
dataList.RemoveRange(1,dataList.Count-1);

}





请给我一个优化的解决方案。

谢谢你

解决方案

如果列表元素确实有不同的类型,那么泛型才有意义,并且所有这些类型都有一个用于过滤的公共(继承)成员删除要删除的对象(或提供任何常用功能)。然后,您将使用泛型类型约束来标识此常见类型。由于你没有指明它,这个问题没有意义。但是,使用泛型的想法可能有意义,如果你做我上面提到的。



此外,在你的删除方法中使用字符串参数不仅仅是愚蠢的,它是犯罪(针对自己)。你总是比较整数属性/字段,所以它应该是整数参数。并且,如果将字符串解析为整数(或任何东西),则使用 int.Parse ,而不是转换。最后,您的代码示例无法编译,因为C#区分大小写。为什么发布不是真正的代码?



让我用一个简单的例子来说明这个想法,这可能与你的情况不符:

  interface  ISno 
{
int Sno {获得; set ; }
}
class 客户:ISno
{
public int Sno { get ; set ; }
}

静态 class 测试
{
内部 静态 void SelectiveDeleteSno< ; T>(列出< T>列表, int snoToMatch)
其中 T:ISno < span class =code-comment> //
此约束允许访问ISno.Sno
{
list.RemoveAll( a = > a.Sno == snoToMatch); // 现在你可以做到这一点
}
}



因此,如果你有任何指定约束的东西,你可以这样做。如果你没有过滤并且不使用某些集合而不使用任何关于元素的知识,那么它可能是任何非指定的元素类型,因此不需要泛型约束。



-SA


我能看到完成你想要的东西的方式是:

通过一个委托到取出值的方法:

  public   void  delete< T>(列出< T> dataList,Func< T,int> getSno, string  MatchedSno)
{
if (!string.IsNullOrEmpty(MatchedSno))
{
int match = Convert.ToInt32(MatchedSno);
dataList.RemoveAll(a = > getSno(a)== match);
}
else
dataList.RemoveRange( 1 ,dataList。计数-1);
}



请注意,我只将 MatchedSno 转换为整数一次,而不是每次都在lambda中。使用 int.TryParse()将优于 Convert.ToInt32(),您可以更干净地处理错误。


这里有一个有趣的挑战是如何使它成为一个通用的方法,但确保传入其中的每个List都可以实现一个名为'Sno的属性。



完成的方法是使用基于接口的方法约束:

  public   interface  ISno 
{
int Sno { set ; get ; }
}

public void delete< t>(List< ; t> dataList, string MatchedSno)其中 T:ISno
{
< span class =code-keyword> if ( string .IsNullOrEmpty(MatchedSno))
{
dataList.RemoveRange(< span class =code-digit> 1 ,dataList.Count-1);
return ;
}

int intSNO = Convert.ToInt32(MatchedSno);

dataList.RemoveAll(itm = > itm.Sno == intSNO);
} < / t > < / t >

测试:定义两个类,一个实现ISno,另一个不实现:

  public   class  HasSno:ISno 
{
public int Sno { set ; get ; }

public HasSno( int sno)
{
Sno = sno;
}
}

public class NoSno
{
public int Sno {设置; get ; }

public NoSno( int sno)
{
Sno = sno;
}
}

现在我们可以测试:

  private   void  SomeButton_Click( object  sender,EventArgs e)
{
var listHasSno = new List< hassno>();
var listNoSno = new 列表< nosno>();

for int i = 0 ; i < 30 ; i ++)
{
int m = i% 5 ; // 系列0~4中的值

listHasSno.Add( new HasSno(m));

listNoSno.Add( new NoSno(m));
}

delete(listHasSno, 3);

// 确认所有'HasSno列表中'Sno == 3被删除
foreach var sno in listHasSno)Console.WriteLine(sno.Sno);

// 这将失败:
// delete(listNoSno,2);
/ / ftype'noSno不能用作类型参数'T'
// 泛型类型或方法中的删除< t>(System.Collections.Generic.List< t>,string)'。
// 没有从'noSno'到'ISno'的隐式引用转换
} < / t > < / t > < / nosno > < / hassno >


Hi all, i have query and i would be really thankful if you could help me.
I have list<customer> with a property name SNO.

I have written a code

Public Void delete(List<Customer> dataList,String MatchedSno)
{
if(!String.IsNullOrEmpty(MatchedSno))
dataList.RemoveAll(a=>a.SNO==Convert.ToInt32(MatchedSno));
else
dataList.RemoveRange(1,dataList.Count-1);

}



But i want to create a generic method with List of Type <t> and now want to achieve the Same i.e.

Public Void delete<T>(List<T> dataList,String MatchedSno)
{
if(!String.IsNullOrEmpty(MatchedSno))
dataList.RemoveAll(a=>a.SNO==Convert.ToInt32(MatchedSno));
else
dataList.RemoveRange(1,dataList.Count-1);

}



Please give me an optimized solution for this.
Thank You

解决方案

Generics only makes sense if you really have different type for the list element, and all those types have a common (inherited) member to be used to to filter out the objects to be removed (or provide any common functionality at all). Then you would use generic type constraints to identify this common type. As you did not specify it, the question does not make sense. However, the idea to use generics may make sense, if you do what I mentioned above.

Besides, using string parameter in your delete method is not just silly, it's a crime (against yourself). You always compare integer property/field, so it should be integer parameter. And, if you parse a string to integer (or anything), uses int.Parse, not Convert. Finally, your code samples could not compile, because C# is case-sensitive. Why posting not real code?

Let me illustrate the idea on a simple example, which may not match your case:

interface ISno
{
    int Sno { get; set; }
}
class Customer : ISno
{
    public int Sno { get; set; }
}

static class Test
{
    internal static void SelectiveDeleteSno<T>(List<T> list, int snoToMatch)
        where T : ISno // this constraint give access to ISno.Sno
    {
        list.RemoveAll(a => a.Sno == snoToMatch); // now you can do it
    }
}


So, if you have anything to specify the constraint, you can do it. If you did not have filtering and had to do something with some collection without using any knowledge on the elements, it could be any non-specified element type, so generic constraint would not be needed.

—SA


The way I can see to accomplish what you seem to want is:
Pass a delegate to the method that pulls out the value:

public void delete<T>(List<T> dataList, Func<T, int> getSno, string MatchedSno)
{
  if(!string.IsNullOrEmpty(MatchedSno))
  {
    int match = Convert.ToInt32(MatchedSno);
    dataList.RemoveAll(a => getSno(a) == match);
  }
  else
    dataList.RemoveRange(1, dataList.Count-1);
}


Note that I convert MatchedSno to an integer only once, not every time in the lambda. Using int.TryParse() would be better than Convert.ToInt32(), you can handle errors more cleanly.


The interesting challenge here is how to make this a generic method, but ensure that every List passed into it for manipulation implements a Property named 'Sno.

The way that is done is with a method constraint based on an Interface:

public interface ISno
{
    int Sno { set; get; }
}

public void delete<t>(List<t> dataList, string MatchedSno) where T : ISno
{
    if (string.IsNullOrEmpty(MatchedSno))
    {
        dataList.RemoveRange(1,dataList.Count-1);
        return;
    }

    int intSNO = Convert.ToInt32(MatchedSno);

    dataList.RemoveAll(itm => itm.Sno == intSNO);            
}</t></t>

Test: Define two classes, one that implements ISno and one that doesn't:

        public class HasSno : ISno
{
    public int Sno { set; get; }

    public HasSno(int sno)
    {
        Sno = sno;
    }
}

public class NoSno
{
    public int Sno { set; get; }

    public NoSno(int sno)
    {
        Sno = sno;
    }
}

Now we can test:

private void SomeButton_Click(object sender, EventArgs e)
{
    var listHasSno = new List<hassno>();
    var listNoSno = new List<nosno>();

    for (int i = 0; i < 30; i++)
    {
        int m = i % 5; // value in series 0~4

        listHasSno.Add(new HasSno(m));

        listNoSno.Add(new NoSno(m));
    }

    delete(listHasSno, "3");

    // confirm all 'HasSno in list with 'Sno == 3 are deleted
    foreach (var sno in listHasSno) Console.WriteLine(sno.Sno);

    // this will fail:
    // delete(listNoSno, "2");
    // ftype 'noSno cannot be used as type parameter 'T' 
    // in the generic type or method delete<t>(System.Collections.Generic.List<t>, string)'.
    // There is no implicit reference conversion from 'noSno' to 'ISno'
}</t></t></nosno></hassno>


这篇关于从列表中删除项目的通用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆