【问题标题】:Creating base Attribute class with a generic property 'value'使用通用属性“值”创建基本属性类
【发布时间】:2015-12-16 11:31:47
【问题描述】:

我所做的是在 C# 中创建了一个“属性”基类。从那里我创建了其他类,这些类继承 Attribute 并根据需要添加任何其他属性。但是,当我尝试创建包含所有这些不同属性的可观察集合时,我会在这里得到一个下划线

private ObservableCollection<Attribute> _attributes;

在'Attribute'下说:使用泛型'Attribute'需要一个类型参数。 Attribute 基类的原因是我可以创建多个属性,如下所示。

属性类

using System.Collections.Generic;

namespace ExampleTool.Model
{
    public class Attribute<TValue>
    {
        public string Key { get; set; }
        public TValue Value { get; set; }
    }

    public class FloatAttr : Attribute<float>
    {
        public string Label { get; set; }
        private float minValue { get; set; }
        private float maxValue { get; set; }
    }

    public class IntAttr : Attribute<int>
    {
        public string Label { get; set; }
        private float minValue { get; set; }
        private float maxValue { get; set; }
    }

    public class StringAttr : Attribute<string>
    {
        public string Label { get; set; }
    }

    public class BoolAttr : Attribute<bool>
    {
        public string Label { get; set; }
    }

    public class ListStringAttr : List<string>
    {
        public string Label { get; set; }
    }
}

ViewModel - 发生错误的地方...

using System.Collections.Generic;
using System.Collections.ObjectModel;
using ExampleTool.Model;
using ExampleTool.Helper;

namespace ExampleTool.ViewModel
{
    public class AttributeViewModel : ObservableObject
    {
        private ObservableCollection<Attribute> _attributes;
        public ObservableCollection<Attribute> Attributes
        {
            get { return _attributes; }
            set
            {
                _attributes = value;
                NotifyPropertyChanged("Attributes");
            }
        }

        public AttributeViewModel()
        {
            //hard coded data for testing
            Attributes = new ObservableCollection<Attribute>();

            FloatAttr floatAttr = new FloatAttr();
            Attributes.Add(floatAttr);

            IntAttr intAttr = new IntAttr();
            Attributes.Add(intAttr);

            StringAttr stringAttr = new StringAttr();
            Attributes.Add(stringAttr);

            BoolAttr boolAttr = new BoolAttr();
            Attributes.Add(boolAttr);

            ListStringAttr listStringAttr = new ListStringAttr();
            Attributes.Add(listStringAttr);
        }
    }
}

解决方案#1 - 只需从基类中移除 value 的属性,并在每个子类中定义它。

public class Attribute
    {
        public string Key { get; set; }
    }

    public class FloatAttr : Attribute
    {
        public float Value { get; set; }
        public string Label { get; set; }
        private float minValue { get; set; }
        private float maxValue { get; set; }
    }

    public class IntAttr : Attribute
    {
        public int Value { get; set; }
        public string Label { get; set; }
        private float minValue { get; set; }
        private float maxValue { get; set; }
    }

    public class StringAttr : Attribute
    {
        public string Value { get; set; }
        public string Label { get; set; }
    }

    public class BoolAttr : Attribute
    {
        public bool Value { get; set; }
        public string Label { get; set; }
    }

    public class ListStringAttr : Attribute
    {
        public List<string> Value { get; set; }
        public string Label { get; set; }
    }

【问题讨论】:

  • 您希望视图如何处理Attributes?它如何知道如何显示不同类型的值?
  • 你和几小时前的问题作者有同样的问题:stackoverflow.com/questions/34305723/…
  • 视图实际需要Attribute 的哪个属性?

标签: c#


【解决方案1】:

您的基本 Attribute 类是一个泛型类型,那么您必须在它的用法中添加类型参数。但是你不能只添加 T:

private ObservableCollection<Attribute<T>> _attributes;

因为 T 不是您的类型参数。您应该添加新的非泛型基类:

public class AttributeBase
{
    public string Key { get; set; }
}

public class Attribute<TValue> : AttributeBase
{
    public TValue Value { get; set; }
}

并像this question一样实现AttributeRetriever:

public Attribute<T> GetAttribute<T>() where T: DatabaseItem, new()
{
    return _attributes.OfType(typeof(Attribute<T>)).FirstOrDefault as Attribute<T>;
}

好消息是,您的 WPF 视图可以在没有类型参数的情况下正常工作,因为 Binding 使用反射。然后,如果您不需要在代码中访问您的属性,您也不需要实现检索器。

【讨论】:

  • 公共静态函数放在哪里?
  • 见上面的编辑,让我知道你对这个解决方案的想法?
  • @JokerMartini 不是静态的,这是我的错。它应该在您需要在代码中检索特定 Attribute 对象的地方实现(例如,在 ViewModel 中)。如果只是在集合中添加元素并在视图中显示,则无需添加此功能。
  • @JokerMartini 在您的解决方案中我看到 Value 属性的重复代码。但它也可以正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-02
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多