C# полиморфизм и шаблоны - PullRequest
0 голосов
/ 30 марта 2020

Этот вопрос, возможно, уже задавался, но я не знаю правильный вопрос, чтобы задать, чтобы найти ответ.

Я пытаюсь создать набор классов (тегов), которые содержат значение и позволяют другим компонентам получать доступ к значению.

Значение равно generi c, что позволит вам создать тег любого типа. Однако мне нужно иметь возможность хранить теги в списке или другой структуре данных, чтобы компонент имел несколько тегов разных типов.

  public abstract class BaseTag
  {
    protected object _value;
    public ushort DataQuality { get; protected set; }
    public virtual object Value => _value;
    public abstract void SetValue(object value, ushort dataQuality = 0);
  }

  public class Tag<T> : BaseTag
  {
    public new T Value
    {
      get => (T)_value;
      private set
      {
        _value = value;
      }
    }
    public override void SetValue(object value, ushort dataQuality = 0)
    {
      Monitor.Enter(_tagSync);

      try
      {
        //If value or quality haven't changed, then do nothing
        if (EqualityComparer<T>.Default.Equals((T)_value, (T)value) && dataQuality == DataQuality)
          return;

        DataQuality = dataQuality;
        Value = (T)value;
      }
      finally
      {
        Monitor.Exit(_tagSync);
      }
    }
  }

Я даже не знаю, задаю ли я еще правильный вопрос.

Может ли кто-нибудь помочь

Как получить возможность иметь список теги; tags [0] .Value <- хотел бы, чтобы это вызывало дочернее значение, но это не так, он возвращает basetag._value, но объекта типа, а не типа </p>

Есть ли более простой способ чтобы это произошло?

1 Ответ

0 голосов
/ 30 марта 2020

вам действительно нужен класс BaseTag?

Вы можете преобразовать его в интерфейс и сделать с явным объявлением интерфейса, как показано ниже:

public interface IBaseTag
{
    object Value { get; }
    ushort DataQuality { get; }
}

public class Tag<T> : IBaseTag
{
    public T Value { get; set; }

    object IBaseTag.Value => Value; // explicit interface implementation

    public ushort DataQuality { get; protected set; }

    public virtual void SetValue(T value, ushort dataQuality = 0)
    {
        //If value or quality haven't changed, then do nothing
        if (EqualityComparer<T>.Default.Equals(Value, value) && dataQuality == DataQuality)
            return;

        DataQuality = dataQuality;
        Value = (T)value;
    }
}

Я пропустил _tagSync функциональный.

Тогда вы можете получить

var b = new Tag<int>(); //child
IBaseTag a = b; //parent

//a.Value and b.Value are both accessible and can be used
if (b.Value.Equals(a.Value) && a.DataQuality == b.DataQuality)
    return;

Вы можете использовать IBaseTag.Value или Tag<>.Value одновременно в соответствии с изоляцией зависимостей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...