简体   繁体   中英

Observe ReactiveObject.Changed of inherited class may or may not work

I try to create a base class, which inherits from ReactiveObject. This class needs to check if any property, including properties of further inheritations, has changed.

My main problem is, that I can't get any reliable testresults. The provided test MAY be green, Running it with VS Live Unit Testing. brings it in red. Moving the classes out of the testproject into a library may or may not get this test green.

So far, the only way to keep it green, is to uncomment this line in the inherited class.

//  Changed.Subscribe(Console.WriteLine);
   [TestClass]
   public class StateBaseTests
   {
      #region Tests

      [TestMethod]
      public void State_ChangesToChanged_PropertyChanged()
      {
         var _item = new MyTest();

         _item.Surname = "Testname";

         Assert.AreEqual(Statetype.Changed, _item.State);
      }

      #endregion

      #region SubClasses

      public enum Statetype
      {
         Added,
         Changed,
         Deleted,
         Detached,
         Unchanged
      }

      public abstract class StateBase : ReactiveObject
      {
         protected StateBase()
         {
            State = Statetype.Unchanged;

            Changed.Select(prop => prop.PropertyName)
                   .Subscribe(UpdateZustand);
         }

         protected void UpdateZustand(string propertyName)
         {
            if(State == Statetype.Unchanged)
               State = Statetype.Changed;
         }

         [Reactive]
         public Statetype State { get; set; }
      }

      private class MyTest : StateBase
      {
         public MyTest()
         {
            //  Changed.Subscribe(Console.WriteLine);
         }

         [Reactive]
         public string Name { get; set; }

         [Reactive]
         public string Surname { get; set; }
      }
   }

Here is a slight adaptation of your sample. Did it using VS Mac Community & NUnit. The test does turn green every time on my machine. As you can see the property name is also printed. On my console it outputs:

State
Surname

Here is the code:

using System;
using System.Reactive.Linq;
using NUnit.Framework;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;

namespace Testy {
    [TestFixture]
    public class Test {
        [Test]
        public void State_ChangesToChanged_PropertyChanged() {
            var _item = new MyTest();
            _item.Surname = "Testname";
            Assert.AreEqual(Statetype.Changed, _item.State);
        }
    }

    public enum Statetype {
        Added,
        Changed,
        Deleted,
        Detached,
        Unchanged
    }

    public abstract class StateBase : ReactiveObject {
        protected StateBase() {
            State = Statetype.Unchanged;

            Changed
                .Select(prop => prop.PropertyName)
                .Subscribe(
                    name => {
                        UpdateZustand(name);
                        Console.WriteLine(name);
                    });
        }

        protected void UpdateZustand(string propertyName) {
            if (State == Statetype.Unchanged)
                State = Statetype.Changed;
        }

        [Reactive]
        public Statetype State { get; set; }
    }

    public class MyTest : StateBase {
        [Reactive]
        public string Name { get; set; }

        [Reactive]
        public string Surname { get; set; }
    }
}

Not sure if this helps, but it it was fun to try it out:).

PS: These are the used package versions:

  • ReactiveUI(.Fody) 10.5.1
  • Nunit 3.12.0
  • NUnit3TestAdapter 3.15.1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM