170

Hypothetically it'd be handy for me to do this:

foo.GetColumnValues(dm.mainColumn, int)
foo.GetColumnValues(dm.mainColumn, string)

where the GetColumns method will call a different method inside depending on the type passed.

Yes, I could do it as a boolean flag or similar, I just wondered if there was a way to perhaps pass this, and then ask:

typeof(arg[1]) or similar...

I could also override the method, use generics, etc - I know there are different ways to do this, I was just curious if this was possible.

Mark Mayo
  • 12,230
  • 12
  • 54
  • 85
  • 1
    My thought exactly, depending on what foo actually is. `foo.GetColumnValues(dm.mainColumn)` may be the way to go. – Major Productions Jun 08 '12 at 20:24
  • 1
    As I said, I realise there are other ways to do this (boolean flag, generics, overriding the method) I just wondered if it was possible as a parameter. – Mark Mayo Jun 08 '12 at 20:27
  • @MarkMayo: I don't understand the question if you _"know that you could also override the method, use generics, etc and you know that there are different ways to do this, you were just curious if this was possible"_. So you know all this but you are curious if it is possible?? – Tim Schmelter Jun 08 '12 at 20:33
  • @TimSchmelter - in the form I describe. i.e. passing it as the 2nd parameter. As it turns out, Reed has kinda said what I was after - where you use (..., Type type). That's what I was looking for. – Mark Mayo Jun 08 '12 at 20:36
  • 1
    Good question, upvoted, I see MS using Type as a parameter for built-in operators in VB.NET e.g. trycast, and have often wished I could do that myself in C#/VB - in the fashion you describe. – Chalky Jun 18 '14 at 23:56

7 Answers7

272

There are two common approaches. First, you can pass System.Type

object GetColumnValue(string columnName, Type type)
{
    // Here, you can check specific types, as needed:

    if (type == typeof(int)) { // ...

This would be called like: int val = (int)GetColumnValue(columnName, typeof(int));

The other option would be to use generics:

T GetColumnValue<T>(string columnName)
{
    // If you need the type, you can use typeof(T)...

This has the advantage of avoiding the boxing and providing some type safety, and would be called like: int val = GetColumnValue<int>(columnName);

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 1
    You can also do an extension method, public static T GetColumnValue(this string columnName){...} then you can say foo.GetColumnValues(dm.mainColumn) – Joshua G Jun 04 '14 at 15:56
  • But how do you define a method that has several arguments and one of them should be a generic? Since the generic is defined before the method argument list, how do you know which one should be a generic then? – BadmintonCat Sep 20 '15 at 09:58
  • 6
    @BadmintonCat `T Foo(string arg1, U arg2)` or similar – Reed Copsey Sep 21 '15 at 17:20
  • 1
    When using the first approach, is there a way to assign a default value to type? (e.g. something like `object GetColumnValue(string columnName, Type type = object)`? That doesn't quite seem to work for me but it would be useful to know. – Dave Cole Sep 21 '18 at 18:11
  • typeof() is a function that takes in a type like int or char or some class name. eg Type c = typeof(char); .Net does not provide us the same privilege. GetColumnValue as mentioned above seems to be the best one can do. – timothy Oct 10 '20 at 03:20
30

foo.GetColumnValues(dm.mainColumn, typeof(string))

Alternatively, you could use a generic method:

public void GetColumnValues<T>(object mainColumn)
{
    GetColumnValues(mainColumn, typeof(T));
}

and you could then use it like:

foo.GetColumnValues<string>(dm.mainColumn);
Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
17

You can pass a type as an argument, but to do so you must use typeof:

foo.GetColumnValues(dm.mainColumn, typeof(int))

The method would need to accept a parameter with type Type.


where the GetColumns method will call a different method inside depending on the type passed.

If you want this behaviour then you should not pass the type as an argument but instead use a type parameter.

foo.GetColumnValues<int>(dm.mainColumn)
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
8
foo.GetColumnValues(dm.mainColumn, typeof(int));
foo.GetColumnValues(dm.mainColumn, typeof(string));

Or using generics:

foo.GetColumnValues<int>(dm.mainColumn);
foo.GetColumnValues<string>(dm.mainColumn);
Danny Varod
  • 17,324
  • 5
  • 69
  • 111
  • 3
    I didn't dv you, but it was probably because you're showing how it would be called and didn't specify the function definition – JConstantine Jun 08 '12 at 20:26
2

You can do this, just wrap it in typeof()

foo.GetColumnValues(typeof(int))

public void GetColumnValues(Type type)
{
    //logic
}
Kevin DiTraglia
  • 25,746
  • 19
  • 92
  • 138
0

You can use an argument of type Type - iow, pass typeof(int). You can also use generics for a (probably more efficient) approach.

0

Use generic types !

  class DataExtraction<T>
{
    DateRangeReport dateRange;
    List<Predicate> predicates;
    List<string> cids;

    public DataExtraction( DateRangeReport dateRange,
                           List<Predicate> predicates,
                           List<string> cids)            

    {
        this.dateRange = dateRange;
        this.predicates = predicates;
        this.cids = cids;
    }
}

And call it like this :

  DataExtraction<AdPerformanceRow> extractor = new DataExtraction<AdPerformanceRow>(dates, predicates , cids);
BorisD
  • 1,611
  • 17
  • 22