Generic class property

11

I have a class with two properties ( Name and Value ). The property Name is a string , already the property Value want to leave the type variable.

public class Field<TValue>
{
    public string Name { get; set; }
    public TValue Value { get; set; }

    public Field()
    {
    }

    public Field(string name, TValue value)
    {
        this.Name = name;
        this.Value = value;
    }
}

In this case it would be simple to instantiate this class with the desired type:

var field1 = new Field<int>("Nome1", 1);
var field2 = new Field<string>("Nome2", "Valor2");

The problem is that I have an intermediate class that uses the class Field as property:

public class MyClass
{
    public string Prop1 { get; set; }
    public int Prop2 { get; set; }

    public Field<TValue>[] FieldArray { get; set; }
}

That is, I want to be able to have a generic% s of Field's , but this last example is not valid for the compiler.

My final goal is something like this:

var myClassObject = new MyClass();
myClassObject.Prop1 = "Teste";
myClassObject.Prop2 = 10;

myClassObject.FieldArray = new Field<TValue>[10];

myClassObject.FieldArray[0] = new Field<string>();
myClassObject.FieldArray[0].Name = "Field1";
myClassObject.FieldArray[0].Value = "Value1";

myClassObject.FieldArray[1] = new Field<int>();
myClassObject.FieldArray[1].Name = "Field2";
myClassObject.FieldArray[1].Value = 2;

Does language allow you to do something like this? What would be the correct way?

    
asked by anonymous 27.09.2017 / 19:11

3 answers

9

In case you have a property or any variable that needs to have different types, you can not keep the static typing and the genericity does not fit in this case, unless you can restrict it a bit, then you can vary, but always on top of a specific common type, you can do something.

You need to analyze if you need this. Often the programmer thinks he needs it, but may have another solution.

public class Program {
    public static void Main() {
        var myClassObject = new MyClass() { Prop1 = "Teste", Prop2 = 10, FieldArray = new Field<dynamic>[2] { new Field<dynamic>("f1", "v1"), new Field<dynamic>("f1", 1) } };
    }
}

public class Field<TValue> {
    public string Name { get; set; }
    public TValue Value { get; set; }

    public Field() {}

    public Field(string name, TValue value) {
        this.Name = name;
        this.Value = value;
    }
}

public class MyClass {
    public string Prop1 { get; set; }
    public int Prop2 { get; set; }
    public Field<dynamic>[] FieldArray { get; set; }
}

See running on .NET Fiddle . And no Coding Ground . Also I put GitHub for future reference .

    
27.09.2017 / 19:22
8

Based on this response from SOEn , you need to have a common base type to be able to "extend" those objects into collections. In the case of string and int , the common base type will be object .

Then your code would look like this

public class Field
{
    public string Name { get; set; }
    public object Value { get; set; }

    public Field()
    {
    }

    public Field(string name, object value)
    {
        this.Name = name;
        this.Value = value;
    }
}

and the class with Field:

public class MyClass
{
    public string Prop1 { get; set; }
    public int Prop2 { get; set; }

    public Field[] FieldArray { get; set; }
}

This should solve your problem and, if necessary, it is always possible to do the processing to make%% strongly typed.

    
27.09.2017 / 19:38
6

What you requested can be done with dynamic or object .

Example:

public class Field<TValue>
{
    public string Name { get; set; }

    public TValue Value { get; set; }

    public Field()
    {
    }

    public Field(string name, TValue value)
    {
        this.Name = name;
        this.Value = value;
    }
}

public class MyClass
{
    public string Prop1 { get; set; }

    public int Prop2 { get; set; }

    public Field<dynamic>[] FieldArray { get; set; }
}

Usage:

    var x = new MyClass();
    x.FieldArray = new Field<dynamic>[5];

    x.FieldArray[0] = new Field<dynamic>();
    x.FieldArray[0].Value = "Teste";

    x.FieldArray[1] = new Field<dynamic>();
    x.FieldArray[1].Value = 1;

See working at .NET Fiddle

    
27.09.2017 / 19:33