Reputation: 771
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
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
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
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
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
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