更新列表中的自定义类<t>

时间:2015-11-11 17:50:05

标签: c# list generics

我正在尝试更新List,它是具体类的接口列表。

我向列表中添加了我感兴趣的每个市场类型,对于此示例,这些市场是A和B

我遍布所有市场,(样本提供3个市场A B&amp; C,我们只对A和B感兴趣)并确定我们感兴趣的市场。

一旦找到,我们将它传递给一个提取方法也是如此,并创建一个Correct Market_类类型的实例。

这一切都运行正常,但是当我尝试使用更新更新列表时,它不会反映在列表中。

以下代码,任何建议?

由于

public class Test
{
    public Test()
    {
        TheMarkets MarketsToUpdate = new TheMarkets();
        List<SpecificCompanyMarket> lstMarks = new List<SpecificCompanyMarket>();

        lstMarks.Add(new SpecificCompanyMarket(1234, "A", "Some HTML DATA HERE"));
        lstMarks.Add(new SpecificCompanyMarket(5874, "B", "Some HTML DATA HERE"));
        lstMarks.Add(new SpecificCompanyMarket(2224, "C", "Some HTML DATA HERE"));

        foreach (var item in lstMarks)
        {
            if (MarketsToUpdate.IsMarketWeAreInterestedIn(item.MarketName))
            {
                ITheMarkets MarkToUpdate = ExtractMarketData(item);

                var obj = MarketsToUpdate.MarketsWeAreInterestedIn.FirstOrDefault(x => x.MarketName() == "A");

                if (obj != null)
                {
                    obj = MarkToUpdate;
                }

            }
        }

        //Look At MarketsToUpdate Now and the item has not changed, still original values

        //I was expecting to see the new values for the fields in A, not the default 0's
    }

    public ITheMarkets ExtractMarketData(SpecificCompanyMarket item)
    {
        ITheMarkets market = null;

        if (item.MarketName.ToUpper() == "A")
        {
            Market_A marketType = new Market_A();
            marketType.SomeValue1 = 123;
            marketType.SomeValue2 = 158253;

            market = marketType;
        }
        //Other Market extractions here

        return market;
    }


}

public class SpecificCompanyMarket
{
    public int MarketId { get; set; }
    public string MarketName { get; set; }
    public string MarketDataHTML { get; set; }

    public SpecificCompanyMarket(int MID, string MName, string MData)
    {
        MarketId = MID;
        MarketName = MName;
        MarketDataHTML = MData;
    }
}

public class TheMarkets 
{
    public List<ITheMarkets> MarketsWeAreInterestedIn = new List<ITheMarkets>();

    public TheMarkets()
    {
        Market_A A = new Market_A();
        Market_B B = new Market_B();

        MarketsWeAreInterestedIn.Add(A);
        MarketsWeAreInterestedIn.Add(B);
    }

    public bool IsMarketWeAreInterestedIn(string strMarketName)
    {
        bool blnRetVal = false;

        foreach (var item in MarketsWeAreInterestedIn)
        {
            if (item.MarketName().ToUpper().Trim().Equals(strMarketName.ToUpper().Trim()))
            {
                blnRetVal = true;
                break;
            }
        }

        return blnRetVal;
    }
}

public interface ITheMarkets
{
    string MarketName();
}

public class Market_A : ITheMarkets
{
    public string LabelType { get; private set; }

    public double SomeValue1 { get; set; }
    public double SomeValue2 { get; set; }
    public double SomeValue3 { get; set; }

    public Market_A()
    {
        LabelType = "A";
    }

    public string MarketName()
    {
        return LabelType;
    }
}

public class Market_B : ITheMarkets
{
    public string LabelType { get; private set; }

    public List<string> SomeList { get; set; }
    public double SomeValue { get; set; }

    public Market_B()
    {
        LabelType = "B";
    }

    public string MarketName()
    {
        return LabelType;
    }
}

3 个答案:

答案 0 :(得分:1)

您正在使用LINQ的firstOrDefault扩展名从marketWeAreInterestedIn列表中提取obj。这是一个新对象,而不是对该列表中obj的引用。因此,该列表中的对象不会反映任何更新。尝试使用'indexof'

答案 1 :(得分:1)

这是一个让你前进的简短例子。遍历列表,找到要更新的对象,创建该类型的新对象,然后在列表中找到原始对象索引并在适当位置覆盖它。您实际上只是用一个不改变现有对象的新对象替换列表中的对象。

foreach (var item in lstMarks)
{
    //your code to get an object with data to update    
    var yourObjectToUpdate = item.GetTheOneYouWant();

    //make updates
    yourObjectToUpdate.SomeProperty = "New Value";

    int index = lstMarks.IndexOf(item);
    lstMarks[index] = yourObjectToUpdate;
}

答案 2 :(得分:1)

您没有在列表中存储“接口列表”。 List<T>存储指向支持T接口的对象的指针数组。一旦你枚举(在你的情况下使用Linq)你的列表,你从列表中复制一个指针,它与列表本身没有任何关联。它只是指向您实例的指针。

要执行您想要的操作,您必须在枚举原始列表的同时构建新列表,根据需要向其添加对象,因此第二个列表将基于第一个列表,但需要应用更改

您也可以在特定索引处替换特定实例,而不是在代码中构建新列表,但要执行此操作,您需要使用for循环枚举列表,并为每个项目了解index

list[index] = newvalue;

但是有第三种解决方案可以直接通过代理它们来更新列表项。这是一个例子

class ItemProxy : T { public T Value { get; set; } }

var list = new List<ItemProxy<MyClass>>();
list.Insert(new ItemProxy { Value = new MyClass() });
list.Insert(new ItemProxy { Value = new MyClass() });
list.Insert(new ItemProxy { Value = new MyClass() });

foreach(var item in list)
if(item // ...)
item.Value = new MyClass(); // done, pointer in the list is updated.

第三个是性能的最佳案例,但最好将此代理类用于代理以外的其他任务。