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