blu
blu

Reputation: 13175

C# Generic Lists

I have a class that is maps to a field in a database. The class only cares about the name of the field and its related .NET type. The type can be string, int, datetime, etc.

class Foo()
{
    string Name { get; set; }
    Type FooType { get; set; }
}

I have another class that inherits from Foo that adds a property for a value. Right now I store the value as an object and use a switch statement to box the value based on the base classes FooType.

class FooWithStuff() : Foo
{
    object Value { get; set; }   
}

Is there way to implement this with generics to give type safety for the values?

Edit: I have made the key requirement bold. When declaring a list say Foo it needs a type. If I were doing this against custom classes I would create and interface and use that. However here I am using int, string, DateTime, etc. Int is a struct, string is an object, so a Foo< object> does not work for both.

Upvotes: 3

Views: 1479

Answers (6)

Tim Jarvis
Tim Jarvis

Reputation: 18815

Yes, in fact you can do away with your inheritance, simply..

public class Foo<T>
{
  public string Name {get;set;}
  public T Value {get;set;}
  public Type FooType
  {
     get
     {
       return typeof(T);
     }
  }
}

Note also, using linq you can simply extract the types you need from the list directly, so if you are just interested in the string fields for some reason you could...

List<object> list = getAllmyFoos();
foreach(Foo<string> sfoo in list.OfType<Foo<string>>())
{
  ...blah
}

Edit : Added FooType.

Upvotes: 0

Quintin Robinson
Quintin Robinson

Reputation: 82325

If you want to add Value to Foo and have Foo be generic you could do...

class Foo<T>
{
    T Value {get; set;}
}

Foo<int> myFoo = new Foo<int>();
myFoo.Value = 7;

Upvotes: 2

Lars M&#230;hlum
Lars M&#230;hlum

Reputation: 6102

Define your class like this:

class Foo<T> : IFoo
{

    public Foo(string name)
    {
        Name = name;
    }

    string Name { get; set; }
    T Value {get; set;}
    Type FooType { get { return typeof(T); } }
}

You could then define the interface IFoo as:

string Name { get; set; }
Type FooType { get; set; }

And declare a list as:

List<IFoo> list = new List<IFoo>();

Upvotes: 8

thinkbeforecoding
thinkbeforecoding

Reputation: 6778

I would recomand using 2 interfaces :

public interface IFoo
{
  string Name {get; }
  Type Type { get; }
  object Value {get; set;}
}

public interface IFoo<T> : IFoo
{
  T Value {get; set}
}

Then implement it :

public class Foo<T> : IFoo<T>
{
   private T value;
   public Foo(string name, T value)
   {
     this.name = name;
     this.value = value;
   }

   public string Name { get { return name; } }
   public Type Type { get { return typeof(T); } }
   public T Value
   {
      get { return value; }
      set { value = value; }
   }

   object IFoo.Value
   {
      get { return value; }
      set { value = (T)value; }  // can check type before
   }
}

This way, you can use the IFoo interface easily in a non generic context too.

Upvotes: -2

xian
xian

Reputation: 4693

class Foo
{
    public string Name { get; set; }
    public Type Type { get; set; }
}

class Bar<T> : Foo
{
    public T Value { get; set; }

    public Bar()
    {
        base.Type = typeof( T );
    }
}

Upvotes: 9

Mike_G
Mike_G

Reputation: 16502

I would use an Interface rather than a generic class inheritance on that.

edit: To clarify. I would use an Interface for Foo, and a generic class for FooWithStuff:

public interface IFoo
{
  string Name{get;set;}
  Type FooType{get;set;}
}

public class FooWithStuff<T>:IFoo
{
   T Value {get;set;}
}

Upvotes: 1

Related Questions