简体   繁体   English

C# 多态性和模板

[英]C# polymorphism and templates

This question may have been asked already, but I don't know the correct question to ask in order to find the answer.这个问题可能已经有人问过了,但我不知道要问正确的问题才能找到答案。

I am attempting to make a set of classes (tags) that hold a value and allow other components to access the value.我正在尝试创建一组包含值并允许其他组件访问该值的类(标签)。

The value is generic, which will allow you to create a Tag of any type.该值是通用的,这将允许您创建任何类型的标签。 However I need to be able to hold the tags within a list or other data structure to allow the component to have multiple tags of multiple types.但是,我需要能够将标签保存在列表或其他数据结构中,以允许组件具有多种类型的多个标签。

  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);
      }
    }
  }

I don't even really know if I am asking the correct question still.我什至不知道我是否还在问正确的问题。

Can anyone help谁能帮忙

How do I get the ability to have a List tags;我如何获得拥有 List 标签的能力; tags[0].Value <- would like this to call the child value, but it doesn't, it returns the basetag._value, but of type object, not type tags[0].Value <- 想要调用子值,但它不会,它返回 basetag._value,但类型为对象,而不是类型

Is there an easier better way to make this happen?有没有更简单更好的方法来实现这一目标?

do you really need the BaseTag class?你真的需要BaseTag类吗?

You can convert it to the interface and do with explicit interface declaration like below:您可以将其转换为接口并使用如下显式接口声明:

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;
    }
}

I've skipped the _tagSync functional.我跳过了_tagSync功能。

Then you can get the然后你可以得到

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;

You can use the IBaseTag.Value or Tag<>.Value in the same time according to the dependency isolation.您可以根据依赖隔离同时使用IBaseTag.ValueTag<>.Value

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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