简体   繁体   中英

how to create a collection of a type that has a generic value type argument

I'm trying to create a collection (list<> or IEnumerable<>) of a custom objet "InventorAttribue" that has 2 properties; Name and Value.

The "Value" property can be of various type so I thought of coding this object like this:

public class InventorAttribute<T> {
public InventorAttribute (string name, T value) {
    Name = name;
    Value = value;
}

public string Name { get; set; }
public T Value { get; set; }
}

Further I plan to use an "AttiributeSet" class to represent the final Autodesk Inventor AttributeSet to be stored in an Inventor's object. Here is the class and where my question stands, because of course, this code does not work as the type 'T' cannot be found (!)

public class AttributeSet
{

public AttributeSet(string category, string name {
    Name = name;
    Attributes = new List<InventorAttribute<T>>();

}

public string Category { get; set; }
public string Name { get; set; }

public List<InventorAttribute<T>> Attributes { get; set; }

public void AddAttribute(string name, T value){
    Attributes.Add(new InventorAttribute<T>(name,value));
}
}

Question:

How can I manage to write this code, and being able to pass the "InventorAttribute.Value" type only at run time through the "AddAttribute" method.

Thanks in advance for greatly appreciated help.

Your AttributeSet class should be also parametrized:

public class AttributeSet<T>

NOTE: you cannot store InventorAttribute<T> parametrized with different T types in Attributes collection. Even if you could do that, how would you consume such collection? You will need to cast Value for each attribute to appropriate type. You will not have any benefits of having generic class here. So create non-generic InventorAttribute which will store values in property of object type.

You're probably imagining some form of inheritance. It doesn't exist here.

An InventorAttribute<string> is not a subclass of InventorAttribute<T> . Nor is it a subclass of InventorAttribute<object> (I mention this since it's usually people's next attempt to define the collection's item type). Each constructed generic type is effectively independent 1 .

If applicable, you may be able to introduce a new base class:

public abstract class InventorAttribute {
    public string Name { get; set; }
    public InventorAttribute (string name) {
         Name = name;
    }
}
public class InventorAttribute<T> : InventorAttribute {
    public InventorAttribute (string name, T value) : base(name) {
    Value = value;
    }

    public T Value { get; set; }
}

And you can now declare your collection to be of non-generic type InventorAttribute . But now you cannot access the Value s until you cast to the more specific type.


1 So far as the type system is concerned. As an implementation detail, the system is able to cleverly JIT only a single version of each method body that is applicable for all reference types. But that doesn't have any visible impact in the type system.

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