循环以更好的方式在 C# 中搜索对象列表

本文关键字:搜索 对象 列表 更好 方式 循环 | 更新日期: 2023-09-27 18:31:25

我有一个foreach循环,它循环播放了一个对象列表。它的意思是将 NavigateUrl 设置为超链接。我的代码如下所示:

foreach (var con in contacts)
        {
            if (con.ContactTypeID == 1)
            {
                FacebookIcon.NavigateUrl = "http://facebook.com/" + con.ContactURL;
            }
        }

我想知道是否有更好的方法可以做到这一点。我将有大约 10 个其他 ContactTypeID,否则我宁愿不再写 9 个。

循环以更好的方式在 C# 中搜索对象列表

您可以使用 LINQ:

var facebookURL = contacts.Where(c => c.ContactTypeID == 1)
              .Select(c => c.url)
              .FirstOrDefault();
if(facebookURL != null)
    FacebookIcon.NavigateUrl = "http://facebook.com/" + facebookURL;

编辑:实际上,您可以从 LINQ 的延迟执行中受益,以便对每种类型的联系人类型重用相同的内容:

var contactType = 1; // facebook
var url = contacts.Where(c => c.ContactTypeID == contactType)
      .Select(c => c.url);
if (url.Any())
    FacebookIcon.NavigateUrl = "http://facebook.com/" + url.First();
contactType = 2;    // google
if (url.Any())
    GoogleIcon.NavigateUrl = "http://Google.com/" + url.First();

编辑2:这是另一种使用字典将所有类型与其URL映射的方法,如果您有数百万种类型,这种方法应该更有效;-)(@MAfifi):

var urlTypeMapping = contacts.GroupBy(c => c.ContactTypeID)
    .ToDictionary(grp => grp.Key, grp => grp.Select(c => c.url));
foreach (var type in urlTypeMapping)
{
    var typeUrl = type.Value.FirstOrDefault();
    if (typeUrl != null)
    {
        switch (type.Key)
        {
            case 1:
                FacebookIcon.NavigateUrl = "http://facebook.com/" + typeUrl;
                break;
            case 2:
                GoogleIcon.NavigateUrl = "http://Google.com/" + typeUrl;
                break;
            default:
                break; //or throw new Exception("Invalid type!");
        }
    }
}

您可以使用 LINQ 来执行所需的操作。

var x = contacts.FirstOrDefault (c => c.ContactTypeID == 1);
if( x != null )
{
   FacebookIcon.NavigateUrl = String.Format ("http://facebook.com/{0}", x.ContactURL);
}

您可以使用 switch

switch (caseSwitch)
{
case 1: 
    FacebookIcon.NavigateUrl = "http://facebook.com/" + con.ContactURL;
    break;
case 2:
    //
    break;
default:
    //
    break;

}

您可以使用 linq。

var con = contacts.FirsOrDefault(c => c.ContactTypeID.Equals(1));
if (con == null)
{
  return;
}
con.NavigateUrl = "http://facebook.com/" + con.ContactURL;

或者,如果您有更多身份证

List<int> ids = new List<int> {1,2,5,7};
contacts.Where(c => ids.Containt(c.ContactTypeID)).ToList().ForEach(item => item.NavigateUrl = "http://facebook.com/" + item.ContactURL);

如果使用 Linq,则应使用 First 或 FirstOrDefault

var url = contacts.FirstOrDefault(c => c.ContactTypeID == 1).NavigateUrl;

使用开关:

foreach (var con in contacts) 
    { 
        switch (con.ContactTypeID) 
        {
          case 1: 
            FacebookIcon.NavigateUrl = "http://facebook.com/" + con.ContactURL; 
            break;
          case 2:
            . . . 
            break;
          . . . 
        } 
    } 

也许是一个精简的 LINQ:

contacts.ForEach(c => { if (c.ContactTypeID  == 1) FacebookIcon.NavigateUrl = "http://facebook.com/" + con.ContactURL;  });

如果你想为每个联系人类型 ID 做"它"== 1。

我假设每个联系人不一定是 Facebook,您需要根据联系人是什么动态设置不同的属性?

你最好的选择是Dictionary<int, Action>或类似的东西,你只是做一些事情,

var setCorrectUrl = new Dictionary<int, Action<Contact>>
{
    // Appropriate entries in here, e.g. (syntax not quite right)
    {
        1,
        (contact) => FacebookIcon.NavigateUrl = contact.ContactURL;
    }
}
foreach (var con in contacts)
{
    setCorrectUrl[con.ContactTypeID](con);
}

好吧,我会对代码进行一些重构。想象一下,他将有 10 种其他类型来实现:)上面提供的解决方案是可行的,但在可扩展性方面不是很优雅。

所以,这是我的解决方案:

1) 实现具有公共联系人属性的基类

public abstract class BaseContact
{
    public string Name { get; set; }
    public abstract string Url { get; set; }
}

2)实现具体类型

public class FbContact : BaseContact
{
    private string _baseUrl = "http://facebook.com/{0}";
    private string _url = string.Empty;
    public override string Url
    {
        get { return _url; }
        set { _url = string.Format(_baseUrl, value); }
    }
}
public class LinkedInContact : BaseContact
{
    private string _baseUrl = "http://linkedin.com/{0}";
    private string _url = string.Empty;
    public override string Url
    {
        get { return _url; }
        set { _url = string.Format(_baseUrl, value); }
    }
}

3)这只是一个用于设置导航URL的辅助类

public static class NavigationCreator
{
    public static void SetUrl(BaseContact contact, HyperLink link)
    {
        link.NavigateUrl = contact.Url;
    }
}

4)一些测试代码来可视化结果

        List<BaseContact> items = new List<BaseContact>();
        for (int i = 0; i < 5; i++)
        {
            BaseContact item;
            if (i % 2 == 0) item = new FbContact(); else item = new LinkedInContact();
            item.Url = "My name " + i;
            items.Add(item);
        }
        foreach (var contact in items)
        {
            HyperLink link = new HyperLink();
            NavigationCreator.SetUrl(contact, link);
            Console.WriteLine(link.NavigateUrl);
        }
        Console.Read();
相关文章: