Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make/design a class which can have different type of members at runtime in C#

Tags:

c#

I have a situation where I need a class which need to contain information about something which varies at runtime, for example:

class Info<T>
{
    public T Max { get; set; }
    public T Min { get; set; }
    public T DefaultValue { get; set; }
    public T Step { get; set; }
    // Some other stuff
}

I have to store many instances of this class in a dictionary but problem is that to use dictionary I have to declare one type e.g.

Dictionary<string, Info<int>> dict = new Dictionary<string, Info<int>>();

In this case I can't add another type of info e.g. Info<double>. I want something like , I have removed generic version in below case.

 {"Price", new Info{Min=100,Max=1000,DefaultValue=200,Step=50}}
 {"Adv", new Info{Min=10.50,Max=500.50,DefaultValue=20.50,Step=1.5}}
 {"Answer", new Info{Min=false,Max=false,DefaultValue=false,Step=false}}

I can use Dictionary<string, Object> dict = new Dictionary<string, Object>();

but then when I get the dict item back I don't know what type is that, I need to know the type as well e.g. for Price it's int and for Adv it's double , how will I know it at runtime?

Actually I want to create a validator(I am using .Net Compact Framework 3.5/can not use any inbuilt system if it exists) for example If I have a class like below..

class Demo
{
    public int Price { get; set; }
    public float Adv { get; set; }

    public static bool Validate(Demo d)
    {
        List<string> err = new List<string>();
        // here I have to get Info about the Price
        // from dictionary, it can be any storage
        Info priceInfo = GetPriceInfo("Price");
        if (d.Price < priceInfo.Min)
        {
            d.Price = priceInfo.Min;
            err.Add("price is lower than Min Price");
        }
        if (d.Price > priceInfo.Max)
        {
            d.Price = priceInfo.Max;
            err.Add("price is above than Max Price");
        }
        // need to do similar for all kinds of properties in the class  
    }
}

So idea is to store validation information at one place (in dictionary or somewhere else) and then use that info at validation time, I also would like to know if I can design the above scenario in a better way ?

Maybe there is a better way to do this , any guidelines please?

like image 588
Embedd_0913 Avatar asked Nov 17 '25 21:11

Embedd_0913


2 Answers

You can use a non-generic base class:

public abstract class Info {
}

public class Info<T> : Info {
}

Now all different generic types inherit from the same base type, so you can use that in the dictionary:

Dictionary<string, Info> dict = new Dictionary<string, Info>();

You can define properties and methods where the interface is not depending on the generic type in the base class, and implement them in the generic class. That way you can use them without specifying the generic type.

For methods where you need the type, you need specific code for each type. You can use the is and as operators to check for a type:

Info<int> info = dict[name] as Info<int>;
if (info != null) {
  int max = info.Max;
}
like image 53
Guffa Avatar answered Nov 19 '25 12:11

Guffa


You could take from Microsoft and mimic the IEnumerable interface and create a .Cast<T>? However, somebody is going to have to know about your type unless you want to get into dynamic (4.0+ only) or reflection. Both of which come with a cost. Maybe you need to rethink your design?

like image 32
Justin Pihony Avatar answered Nov 19 '25 12:11

Justin Pihony