简体   繁体   English

创建具有通用属性“值”的基本Attribute类

[英]Creating base Attribute class with a generic property 'value'

What I've done is created a base class of 'Attribute' in C#. 我所做的是在C#中创建了“属性”的基类。 From there I created other classes which inhert Attribute and add any additional properties as necessary. 从那里,我创建了其他继承Attribute的类,并根据需要添加了任何其他属性。 However when I try to create my observable collection which contains all these various attributes I get an underline here 但是,当我尝试创建包含所有这些各种属性的可观察集合时,在此处得到下划线

private ObservableCollection<Attribute> _attributes;

under ' Attribute ' saying: Using the generic type 'Attribute< TValue >' requires one type arguments. 在“ 属性 ”的说法下:使用通用类型“属性<TValue>”需要一种类型参数。 The reason for the base class of Attribute is so I can create multiple attributes as seen below. 之所以使用Attribute作为基类,是因为我可以创建多个属性,如下所示。

Attribute Class 属性类别

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 - where error occurs... 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);
        }
    }
}

Solution idea #1 - simply remove the property of value from the base class and define it in each sub class. 解决方案思路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; }
    }

Your base Attribute class is a generic type, then you must add type argument to it's usage. 您的基本Attribute类是通用类型,那么必须在其用法中添加type参数。 But you can't add just T: 但是您不能仅添加T:

private ObservableCollection<Attribute<T>> _attributes;

because T is not your type parameter. 因为T不是您的类型参数。 You should add new non-generic base class: 您应该添加新的非通用基类:

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

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

And implement AttributeRetriever like in this question : 并像这个问题一样实现AttributeRetriever:

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

Good news are that your WPF View can works fine without type parameter because Binding uses reflection. 好消息是,由于绑定使用反射,因此WPF视图可以在没有类型参数的情况下正常工作。 Then if you no need to have an access to your properties in code you no need to implement retriever too. 然后,如果您无需访问代码中的属性,则也无需实现检索器。

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

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