Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
238 views
in Technique[技术] by (71.8m points)

c# - Method overloads which differ only by generic constraint

I've run into a bit of a problem, which I simply cannot find a good work-around to.

I want to have these 3 overloads:

public IList<T> GetList<T>(string query) where T: string
public IList<T> GetList<T>(string query) where T: SomeClass
public IList<T> GetList<T>(string query) where T: struct

Obviously the first constraint won't even compile alone, so that's my first issue. (I realise I could just make it IList but I want the same syntax for the three)

Anyway the reason for all this, is these methods are part of a wrapper around executing SQL queries against a database - I want to be able to return the result as a list of strings (in case someone selects a varchar column), a list of valuetypes (int, float, whatever) or a list of classes (these classes represent tables, and thus contains multiple columns)

I hope that part was somewhat understandable :-)

Anyway my big problem is obviously that I cannot make these overloads, since they use the same name and parameterlist.

Also I cannot merge them into the same method, since I need to call a method on SomeClass in that implementation, so unless I want to do some heavy typecasting, or worse, reflection - I need that constraint.

I realise that what I'm trying to do isn't possible, so what I'm searching for is a good approach, that'll mimic my intentions.

If some of this is a bit unclear, feel free to ask :-)

Edit:

Here's my current code for the "where T: SomeClass" version. I'm trying to add support for string/valuetypes to this current code, so maybe my initial approach is just plain wrong - any ideas are welcome basically :-)

public IList<TValue> GetList<TValue>(string query) where TValue : DbTable, new()
{
    DataSet dataSet = GetDataSet(query);
    IList<TValue> result = new List<TValue>();

    if (dataSet.Tables.Count > 0)
    {
        foreach (DataRow row in dataSet.Tables[0].Rows)
        {
            TValue col = new TValue();
            col.Fill(row);
            result.Add(col);
        }
    }

    return result;
}

As you can see I need the exact type of DbTable in order to new the proper constructor. Fill is an abstract method of DbTable (which is an abstract class).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As you note; there aren't any good options for this. You might consider different names (rather than overloads) - GetStringList etc.

However, I wonder whether it would be simpler to drop the constraint. A single type-check with "as" isn't exactly "heavy" type-casting, and it might save a lot of pain.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...