C#: How to use generic method with "out" variable
Asked Answered
O

4

8

I want to create a simple generic function

void Assign<T>(out T result) 
{
  Type type = typeof(T);
  if (type.Name == "String")
  {
     // result = "hello";
  }
  else if (type.Name == "Int32")
  {
     // result = 100;
  } 
  else result = default(T);
}

Usage:

int value;
string text;

Assign(value); // <<< should set value to 100
Assign(text); // <<< should set text to "hello"

My question is how do you program the code to set these values ie. the missing codes in comment section.

Thanks for any help.

Overstock answered 14/11, 2009 at 21:56 Comment(0)
B
16

It looks like in this case maybe you're doing it to try to avoid boxing? Difficult to say without more information, but for this specific example, it'd be much easier and probably less bug-prone to just use method overloading:

void Assign(out string value)
{
   //...
}

void Assign(out int value)
{
   //...
}

For the purposes of learning specifically what is wrong here, you do need to cast a value to an object before casting it to the generic type:

(T)(object)"hello world!";

Which IMO is pretty nasty and should be a last resort - certainly doesn't make your code any cleaner.

Any time you do type-checking of generic parameters, it's a good indication generics are not the right solution to your problem. Doing generic parameter type checks makes your code more complex, not simpler. It makes one method responsible for different behaviors based on type, instead of a series of single methods that are easy to change without accidentally affecting the others. See Single Responsibility Principle.

Brogdon answered 14/11, 2009 at 22:2 Comment(0)
S
4

First of all that's a very bad pattern. You shouldn't use this kind of pattern. Maybe if you describe what you really want to achieve there will be better answers.

Code below works, but as I said writing code this way is a bad idea.

    void Assign<T>(out T result) 
    { 
        Type type = typeof(T); 
        if (type.Name == "String") 
        { result = (T) ((object)"hello"); } 
        else if (type.Name == "Int32") 
        { result = (T) ((object)100); } 
        else result = default(T); 
    }

And usage:

        int value;
        string text;

        Assign(out value);
        Assign(out text);
Stephniestepladder answered 14/11, 2009 at 22:10 Comment(0)
T
1
public T GetObject<T>(string val)
{
    T _object = default(T);
    _object = (T)Convert.ChangeType(val, typeof(T));
    return _object;
}
Tinsmith answered 7/9, 2011 at 7:28 Comment(0)
D
0

Here is one way:

static void Assign<T>(out T result) { 
    Type type = typeof(T);
    if (type.Name == "String") {
        result = (T)Convert.ChangeType("hello", typeof(T));
    }
    else if (type.Name == "Int32") {
        result = (T)Convert.ChangeType(100, typeof(T));
    }
    else {
        result = default(T);
    }
}

But this code smells really bad and goes against the point of generics (instead use overloaded methods). I hope this doesn't end up in production code somewhere and is merely for edification.

Duleba answered 14/11, 2009 at 22:3 Comment(2)
Thanks a lot; this works. The reason why I am using generic approach is to simplify my code. Because the "assign code" is only needed for a specific type (eg. string); it would be bad to create overloaded functions for every possible types out there. result = default(T) // is the common behaviorOverstock
I don't agree with you. I think overloading is exactly for that. Use generics only when needed.Geiss

© 2022 - 2024 — McMap. All rights reserved.