简体   繁体   中英

Polymorphism in Generic types

I have a Generic struct that represents a dynamic value, max and min values and some other fields, the struct increases the dynamic value until reaches maximum and decreases until reaches minimum - then cycles back and forth. The problem comes when I want this struct to represent several numeric value types: double, uint, int32, float... and also store several structs in one list. So what I get is a list of this struct instances, which forces me to choose the struct type for the entire list - but I want various types in one list. How can I implement such thing? I tried using constraints and make "where T : object" but it says I cannot use the Object class as a constraint...

public struct eField<T> where T : struct
{
    private string _fieldName;
    private T _value;
    private T _minVal;
    private T _maxVal;
    private double _duration;
}

public class Device
{
    private List<eField> _fields;
}

Of course it will make up an error stating that eField must get a type parameter T>, again I want the list to have several types of the struct not only one type for the entire list

Based on your examples, it looks like you want to use where T: struct so you restrict to value types.

Edit

public interface IeField { }

public class eField<T> : IeField where T : struct
{
    private string _fieldName;
    private T _value;
    private T _minVal;
    private T _maxVal;
    private double _duration;
}

And to use it.

List<IeField> fields;
fields.Add(new eField<int>());
fields.Add(new eField<uint>());
fields.Add(new eField<double>());

check out this post C# - Multiple generic types in one list

Your problem is going to be that eField<int> and eField<float> don't have a common ancestor type (aside from object). You'd either need to have:

private List<object> _fields;

And this list could contain an eField<int> or eField<float> , but it could contain other things too. Or you could use a base class or interface:

public interface IField { ... }
public struct eField<T> : IField {...}

In this case, you could have a List<IField> . If the methods on IField are NOT generic (void DoStuff()) then you can code against it. If IField has generic methods (it is IField<T> ) then you are back in the same boat, I guess. But presumably if you are writing code against all the items in the list, there will be something in common among them.

You could wrap the access to list with some mutator and accessor.

public Device addField<T>(eField<T> field) where T : struct {
   this.fieldList.add(field);

  return this;
}

Then the list can be List<Object> . If you enclose that list properly then you have also the type safety assured.

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