Calling a generic method that has a return value

O

Otis Mukinfus

I've been wrestling with this for a while and can't figure it out.

I have a generic method with the following signature:


//this compiles OK
public abstract class DataMethod
{
public abstract T Select<T>();
}

I want to call it like this:


public override T Select<T>()
{
......
}

But when I compile I get various types of compile errors depending on how I try
to do the code in the overridden method.

Here is what I have tried:

public override T Select<T>()
{
T = new Dictionary<string, DxccCountry>();
}
Error 1 'T' is a 'type parameter' but is used like a 'variable'

I've tried all the ways I know of to get this to work.

T t = new Dictionary<string, DxccCountry>();

Error 1 Cannot implicitly convert type
'System.Collections.Generic.Dictionary<string,N5GE.HamLib.Core.DxccCountry>' to
'T'

Is it not possible to use a generic method with a return type without passing it
into the method as a parameter?
Good luck with your project,

Otis Mukinfus
http://www.arltex.com
http://www.tomchilders.com
 
B

Barry Kelly

Otis said:
I have a generic method with the following signature:
public abstract class DataMethod
{
public abstract T Select<T>();
}

I want to call it like this:

public override T Select<T>()

Yep, that looks right. When you override a generic method, you override
it for all values of the type parameters.
But when I compile I get various types of compile errors depending on how I try
to do the code in the overridden method.
public override T Select<T>()
{
T = new Dictionary<string, DxccCountry>();
}
Error 1 'T' is a 'type parameter' but is used like a 'variable'

You can't assign to a type parameter. T receives a value sent by the
caller. What if someone polymorphically calls DataMethod.Select<int>()?
How would that work when you've tried to assign this Dictionary said:
Is it not possible to use a generic method with a return type without passing it
into the method as a parameter?

There seems to be a faulty assumption underlying what you're saying
there. The problem has nothing to do with return types. The type
arguments are always passed in by the caller. The callee (Select<> in
your case) doesn't get to choose the value of T. Tha caller does.

-- Barry
 
M

Marc Gravell

Consider your line:
T t = new Dictionary<string, DxccCountry>();

Now; if <T> is <int>, this reads:
int t = new Dictionary<string, DxccCountry>();
(and then presumably "return t").

Which clearly isn't going to work. Only valid casts are legal. If you
know it will cast at runtime, sometimes you need to cast (/box) to
object and back for this to work. However, the above clearly never will
work.

If you mean to return a dictionary, then perhaps something like:

Dictionary<string, T> dict = new Dictionary<string, T>()

etc. Other options include adding "where" clauses etc to the type of T,
or using interfaces etc. If you can expand on what you want, we can
help clarify.

Marc
 
O

Otis Mukinfus

Consider your line:
T t = new Dictionary<string, DxccCountry>();

Now; if <T> is <int>, this reads:
int t = new Dictionary<string, DxccCountry>();
(and then presumably "return t").

Which clearly isn't going to work. Only valid casts are legal. If you
know it will cast at runtime, sometimes you need to cast (/box) to
object and back for this to work. However, the above clearly never will
work.

If you mean to return a dictionary, then perhaps something like:

Dictionary<string, T> dict = new Dictionary<string, T>()

etc. Other options include adding "where" clauses etc to the type of T,
or using interfaces etc. If you can expand on what you want, we can
help clarify.

Marc


Thanks, Guys.

I think I must be taking the wrong approach to doing what I want.

I have a class named CountryTable:

public class CountryTable
{
....
}

Which I want to use to call stored procedures from a database for a table Named
"CountryTable". I want to have methods in the class name Select, Update, Delete
and Insert.

The reason I am trying to use generics for this is to reduce the amount of code
I have to write, since I have many more tables that I want to access in this
manner.

I could use overloaded methods to do this but if I make a Select method with the
following signature:
public Dictionary<string, DxccCountry> Select();

I have used up my overloads for that method.

I was hoping I could use a generic return to avoid passing a parameter to avoid
compiler errors. I could do this to accomplish the overloading:
public Dictionary<string, DxccCountry> Select(Dictionary<string, DxccCountry>
countries)
{
// do some stuff
return countries;
}

and then :
public List<DxccCountry> Select(List<DxccCountry> countries)
{
//do some stuff
return countries;
}

IMHO that's not good practice.

I guess my trouble here is not knowing how to implement the abstract method from
the DataMethod class.

What I was hoping to end up with was something like this in the caller:

CountryTable tbl = new CountryTable();

Dictionary<string, DxccCountry> countries = tbl.Select();

Obviously I missed the mark somewhere on the way ;o)

Good luck with your project,

Otis Mukinfus
http://www.arltex.com
http://www.tomchilders.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top