MindFold
MindFold

Reputation: 771

Generic List of different types in C#

I want to build a form entity, which should contain form form fields, so I want to have a class that looks something like this:

public abstract class form
{
    public string FormName;
    public IList<FormField> Fields;
}

I want my FormField class to have one method: getValue, but I want it to be generic, so getValue would not return an Object but the actual value of the object.

Upvotes: 2

Views: 741

Answers (5)

Sunny
Sunny

Reputation: 6346

Please see the complete code below. My solution works like:

var myForm = new Form();
var int_value = myForm.Fields
           .OfType<IntegerFormField>()
           .First(c => c.Name == "c1").GetValue();
var decimal_value = myForm.Fields
           .OfType<DecimalFormField>()
           .First(c => c.Name == "c2").GetValue();

The field interfaces:

    public interface IFormField
    {
        object GetValue();
        string Name { get; }
    }

    public interface IFormField<T> : IFormField
    {
        T GetValue();

    }

The abstract base class for all form fields:

abstract class FormFieldBase<T> : IFormField<T>
        {
            private readonly T _value;

            public FormFieldBase(T value, string name)
            {
                _value = value;
                Name = name;
            }

            #region IFormField<T> Members

            public virtual T GetValue()
            {
                return _value;
            }

            #endregion

            #region IFormField Members

            object IFormField.GetValue()
            {
                return _value;
            }

            public string Name { get; private set; }

            #endregion
        }

Two sample form field implementation:

class IntegerFormField : FormFieldBase<int>
{
     public IntegerFormField(int value, string name) : base(value, name) { }
}

class DecimalFormField : FormFieldBase<decimal>
{
     public DecimalFormField(Decimal value, string name) : base(value, name) { }
}

The Form Class:

class Form
    {
        public IList<IFormField> Fields
        {
            get
            {
                return new List<IFormField>(){
                        new IntegerFormField(10, "c1"), 
new DecimalFormField(200, "c2")
                 };
            }
        }
    }

HTH

Upvotes: 1

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391634

Unfortunately there is no way to create a single generic list containing objects, that each have a different return type for a given method, like the one you want.

The best you can do is an interface, or base class, and a method that returns Object.

This means you will have to cast, but then, you would have to do that anyway.

How would this code work if you could have different return types:

FormField f = _Fields[0];
?? x = f.GetValue();

Upvotes: 3

AndreyAkinshin
AndreyAkinshin

Reputation: 19061

public abstract class Form {
    public IList<FormField> Fields;
    public string FormName;
}

public class FormField {
    private Object field;

    public T getValue<T>() {
        return (T) field;
    }
}

Upvotes: 1

recursive
recursive

Reputation: 86144

This will work:

public abstract class Form<T>{
  public string FormName;
  public IList<IFormField> Fields;
}

public class FormField<T> : IFormField{
    public T getValue() { return default(T); }

    object IFormField.getValue() {  
        return this.getValue();
    }
}

public interface IFormField { 
      object getValue();
}

Upvotes: 3

Derick Bailey
Derick Bailey

Reputation: 72888


public abstract class Form<T>{
  public string FormName;
  public IList<FormField<T>> Fields;
}

public class FormField<T>{
  public T getValue { ... code here ...  }
}

Upvotes: 1

Related Questions