【问题标题】:Updating different Objects that have same properties更新具有相同属性的不同对象
【发布时间】:2017-09-12 18:21:43
【问题描述】:

在我的代码中,我有三个(或更多...)不同的对象,它们都具有相同的属性(例如 TrackingItemType、ReaderID 等)

它们是从 CounterBase 派生的(它没有所需的属性,但有其他属性)。

现在我想遍历这些对象的集合。在集合中,所有三个对象都可以出现。因此,目前我已经为每个对象分别实现了“update”。

问题:如何避免重复编写代码?有没有 模式可用于更新具有相同的不同对象 属性?!

谢谢!

感兴趣的方法:

    private void UpdateTrackingCounters(Reading readingData, TrackingItemType trackingItemType, string trackingCounterType)
    {
        try
        {
            foreach (CounterBase counter in this.TrackingCounters)
            {
                if (typeof(TrackingSimpleCounter).IsInstanceOfType(counter))
                {
                    TrackingSimpleCounter trackingCounter = (TrackingSimpleCounter)counter;

                    if (trackingCounter.TrackingCounterType == trackingCounterType)
                    {
                        if ((trackingCounter.ReaderID == 0
                            && trackingCounter.TrackingItemType == null)
                            || (trackingCounter.ReaderID == 0
                                && trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
                            || (trackingCounter.ReaderID == readingData.ReaderId
                                && trackingCounter.TrackingItemType == null)
                            || (trackingCounter.ReaderID == readingData.ReaderId
                                && trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
                            )
                        {
                            trackingCounter.IncreaseOne();
                        }
                    }
                }
                else if (typeof(TrackingIntervalBasedRollingCounter).IsInstanceOfType(counter))
                {
                    TrackingIntervalBasedRollingCounter trackingCounter = (TrackingIntervalBasedRollingCounter)counter;

                    if (trackingCounter.TrackingCounterType == trackingCounterType)
                    {
                        if ((trackingCounter.ReaderID == 0
                            && trackingCounter.TrackingItemType == null)
                            || (trackingCounter.ReaderID == 0
                                && trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
                            || (trackingCounter.ReaderID == readingData.ReaderId
                                && trackingCounter.TrackingItemType == null)
                            || (trackingCounter.ReaderID == readingData.ReaderId
                                && trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
                            )
                        {
                            trackingCounter.IncreaseOne();
                        }
                    }
                }
                else if (typeof(TrackingTriggerBasedRollingCounter).IsInstanceOfType(counter))
                {
                    TrackingTriggerBasedRollingCounter trackingCounter = (TrackingTriggerBasedRollingCounter)counter;

                    if (trackingCounter.TrackingCounterType == trackingCounterType)
                    {
                        if ((trackingCounter.ReaderID == 0
                            && trackingCounter.TrackingItemType == null)
                            || (trackingCounter.ReaderID == 0
                                && trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
                            || (trackingCounter.ReaderID == readingData.ReaderId
                                && trackingCounter.TrackingItemType == null)
                            || (trackingCounter.ReaderID == readingData.ReaderId
                                && trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
                            )
                        {
                            trackingCounter.IncreaseOne();
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            this.Trace.Error(ex);
        }
    }

【问题讨论】:

    标签: c# object


    【解决方案1】:

    定义一个包含你需要的属性和方法的接口:

    interface ITrackable
    {
        int ReaderID;
        string TrackingItemType;
        void IncreaseOne();
    }
    

    并将其添加到每个拥有它们的类的声明中:

    class TrackingSimpleCounter : CounterBase, ITrackable
    
    class TrackingIntervalBasedRollingCounter: CounterBase, ITrackable
    
    class TrackingTriggerBasedRollingCounter : CounterBase, ITrackable
    

    如果所有类都真正共享这些属性,则您不必实现任何接口,因为它已经存在。

    那么你只需要

    foreach (ITrackable counter in this.TrackingCounters)
    {
        if ((counter.ReaderID == 0 && counter.TrackingItemType == null)
        || (counter.ReaderID == 0 && counter.TrackingItemType == counter.TrackingItemType)
        || (counter.ReaderID == readingData.ReaderId && counter.TrackingItemType == null)
        || (counter.ReaderID == readingData.ReaderId && counter.TrackingItemType == counter.TrackingItemType)
        )
        {
            counter.IncreaseOne();
        }
    }
    

    尽管除非我误解了你的逻辑,你真正需要的是:

    foreach (ITrackable counter in this.TrackingCounters)
    {
        if (counter.ReaderID == 0 || counter.ReaderID == readingData.ReaderID)
        {
            counter.IncreaseOne();
        }
    }
    

    或者如果你想使用 LINQ:

    foreach (var counter in this.TrackingCounters.OfType<ITrackable>().Where(c => c.ReaderID == 0 || c.ReaderID = readingData.ReaderID))
    {
        counter.IncreaseOne();
    }
    

    【讨论】:

    • 第一个听起来像是一个很好的解决方案。不幸的是,C# 接口可能不包含字段/属性,仅包含方法。 //编辑:添加 getter / Setter 时可以正常工作。我会尽力提供反馈!
    【解决方案2】:

    分解

    您可以将公共属性提取到一个新的公共对象中,并使您的两个类都具有对该对象的引用属性。

    这样,当您更新此对象时,您的两个原始对象都将具有最新的值,而不会忘记更新其中一个属性的风险。

    【讨论】:

      猜你喜欢
      • 2016-01-04
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 2021-05-02
      • 1970-01-01
      • 2012-06-27
      • 2015-06-30
      • 1970-01-01
      相关资源
      最近更新 更多