Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Is it acceptable to have a dummy generic parameter in the parameters list in order to save method consumers from the need to specify type arguments? For example -

public T Generate<T>(int paramForInstance) where T : MyClass {
    return MyClass.SomeFactoryMethod<T>(paramForInstance);
}

//calling code needs to specify type
MyDerivedClass instance = Generate<MyDerivedClass>(5);

public T Generate<T>(int paramForInstance, T dummy) where T : MyClass {
    return MyClass.SomeFactoryMethod<T>(paramForInstance);
}

//calling code needs to provide a "sample" to enable type inference
MyDerivedClass instance = null;
instance = Generate(5,instance);

The assumption here is that if junior other devs on the team don't need to think about generics, they're less likely to kick.

A Little Background (feel free to skip this)

A couple weeks ago, a management-developer type in my team freaked out when he saw code (my code) that looked like this:

//conversion methods, using generics
private static TResult? IfNotDangerous<TResult>
  (SomeType firstThing, string name, Func<object, TResult?> conversion) 
  where TResult : struct
{
    return IfNotDangerous(firstThing, name, 
          (any, dummy) => conversion(any), (TResult?)null);
}

private static TResult IfNotDangerous<TResult>
  (SomeType firstThing, string name, Func<object, TResult, TResult> conversion,
  TResult defaultValue)
{
    if (firstThing == null) return defaultValue;
    if (!firstThing.Contains(name)) return defaultValue;
    if (firstThing[name] == DangerousValue) return defaultValue;
    return conversion(firstThing[name], defaultValue);
}

The complaint he had was, "Why are you using a struct?! That's so resources-heavy! And what does 'where' mean? Nobody on the senior development end knows what that does - I've asked them all!"

After overcoming my self-pity, I found a way around that didn't use generics for this particular method. Appeasement was achieved. But I'd like to avoid trouble in the future, if possible.

EDIT

I appreciate all the encouragement, but the question was not "should I look elsewhere for work?" - it was "is this a usable workaround?"

share|improve this question
    
Seriously, this is not the type of code a a manager is supposed to comprehend, and accordingly, should not critique! –  Emmad Kareem Dec 18 '11 at 8:54
    
@EmmadKareem He's a developer with some management responsibility. –  sq33G Dec 18 '11 at 8:56
    
is the downvoter suggesting that I should drop generics altogether, or that I should drop job security altogether? ;) –  sq33G Dec 18 '11 at 10:04
    
thanks for the reply. I did not downvote. –  Emmad Kareem Dec 18 '11 at 10:14
5  
I'm sorry to say this, but someone who says something like your managed and colleagues said is senior in age only. :p A senior dev should 1) probably already know about this and 2) relish the opportunity to learn it otherwise... –  Max Dec 18 '11 at 10:44

7 Answers 7

up vote 27 down vote accepted

Sad to see programmers that do not move along with the times.

The fact is that generics have been part of C# and .NET since version 2 and LINQ since version 3. These are no longer cutting edge new techniques.

Instead of "Protecting" them you should be teaching them. Start a weekly tutorial (over lunch if you don't have buy-in) for all developers who are interested in staying current.

The fact is that if they bring in a new senior, chances are they would also be using generics and LINQ. Keeping these "hidden" or not using them is a disservice to the other developers and the company.

If you are told to not use generics and LINQ at all, I would sadly conclude it is time to look for a job where developers don't cripple themselves.


Update:

Since you don't seem to think the above answers the question "is this a usable workaround?" I will answer now:

No it isn't. It is an abuse of generics and has too much "magic" - it is even less understandable than the straight generic code and if any of your colleagues will have to delve into it, they will not be able to figure it out.

The fact that it works and does what you want it to (hide the use of generic) is besides the point. It is opaque and even the usage is not idiomatic (giving a "prototype" to the function for it to work).

share|improve this answer
    
I actually do tutorials whenever there's downtime (outages, breaks, whatever) - but management and the senior team do not attend. To be fair, they're in a different location. –  sq33G Dec 18 '11 at 9:56
1  
@sq33G - Anyone who develops should at least be invited. If the developer (?) who freaked out on you is developing, he should be interested in attending. If he isn't, he has no business looking at code. –  Oded Dec 18 '11 at 9:58
1  
+1: Totally agree. Time to move on. Working for such luddites will likely limit your appeal to future employers. –  Jim G. Dec 18 '11 at 10:03
2  
+1: I fail to see the difference between "don't use generics," "don't use a ternary operator," and "don't use the not (!) operator." They're all fundamental parts of the toolkit. –  pdr Dec 18 '11 at 10:22
1  
@pdr - It's the good old "we don't use what we don't understand". I have had the same experience a few years ago when asking why interfaces were not being used. –  Oded Dec 18 '11 at 10:24

From the moment they do not allow you to use the full features of the language (a language which, I presume, was chosen by them, not you,) anything goes. Is it acceptable? Sure it is. I would never do such a thing, but it seems like you have to. And it will work.

But if I were in your shoes I would go all the way with it: I would set the compatibility level of the compiler (in project options) so that language constructs that they consider unacceptable cannot even compile, which would mean that the entire shop would be coding in C# 1.0. And I would start looking for another job.

share|improve this answer

The way I see your question is as follows:

Should I write code which doesn't follow the standard conventions and will teach people who don't know generics bad habits, or should I use them the way they're intended to be used?

Viewed from that perspective, I think it answers itself.

In answer to "What does where mean?" you could send an e-mail linking to http://msdn.microsoft.com/en-us/library/6b0scde8(v=vs.80).aspx explaining that although MS have clearly borked the "Other versions" link, the documentation of where clauses from VS2005 is still valid.

share|improve this answer
1  
Actually, I was asking "How nonstandard is this, and how likely is it to teach bad habits to people not yet familiar with generics?" –  sq33G Dec 18 '11 at 17:53
2  
@sq33G, fair enough, I misunderstood slightly. In that case the answers are "It's non-standard enough that if I saw it in a code review I'd assume you didn't know generics properly"; and "Very likely". –  Peter Taylor Dec 18 '11 at 23:47

The introspection about whether you're making code too complicated or if it is reasonable to expect others to be about to understand and use your code is a good thing. However, on this particular snippet

MyDerivedClass instance = null; 
instance = Generate(5, instance); 

I do not like it. In my view, this does not make the code simpler. And it is obviously no more succinct. You haven't saved the developer from having to specify the class type for the generic method call, you have simply moved where it is specified. Either way, you've explicitly stated the type. You're also making me wonder what the method might be doing with instance, why I am reassigning it, etc. (Keep in mind, someone may very well "new up" or otherwise have an instance prior to the method call.) For an experienced* developer, this might not be a problem. For the junior you are trying to shelter?

No, I would opt for what should be simple enough to reason about.

var instance = Generate<MyDerivedClass>(5); 

You certainly want to make code as easy to read, use, and decipher as possible, but creating overloads with degenerate parameters is not likely the solution.


(*) I have recently been involved in helping to interview candidates for roles on my current team. Let's just say the "experienced developers" aren't nearly as experienced as you and I might desire and they might believe. These developers with 5, 8, even 20 years of experience would not understand even your simpler snippet. These are people that have been in the industry for years, have been developing C# since 1.1 or 2.0. They are also people who still cannot reason about generics, their go-to collection of choice is still ArrayList, they can't adequately describe much less implement polymorphic behaviors, etc., I don't know what to say. Perhaps they simply haven't been pushed at their prior roles. Maybe they're not as passionate about development, or resistant to change. Maybe they're just cargo cult. Suffice it to say, I can sympathize with your plight.

share|improve this answer

I think you absolutely should not do this.

You are not really helping anyone, even though I understand that's what you're trying. But in the end, you are hindering understanding of the static type system by concealing something fundamental. I mean it is not like we're talking covariance/contravariance or higher order types here.
These are simple, first order type parameters with constraints. This is something every programmer should understand. If they don't then they should learn it, and they really aren't willing to, they should code in a dynamic language instead (or be fired if you ask me).

The point of static type systems is to encode your domain knowledge into language semantics. The more powerful the type system, the harder it is to learn, but the more safety you will get automatically. This is an investment of maybe half a day of tutoring at most, that will start to pay off within weeks. Your code base will become more robust, thereby more flexible and thereby the cost of responding to requirement changes and debugging in general will be cut considerably.

If you really feel you must do this, then I guess you should do something like (not sure how this should actually look in C#):

public T Generate<T>(Class<T> theClass, int paramForInstance) where T : MyClass {
    return MyClass.SomeFactoryMethod<T>(paramForInstance);
}
//which should make this possible
var instance = Generate(MyDerivedClass, 5);

The point is, that you're virtually using type parameters here. Once your co-workers accept that, transitioning to Generate<MyDerivedClass>(5) is just a small step for them, but a giant leap for your team ;)

share|improve this answer
    
Let's not be too generous here. I'm not trying to help anyone, I'm trying to write code that makes sense. In order to do this without freaking people out, I'd like to make it possible to use my code as widely as possible throughout the code base without forcing callers to include type parameters in their call. In any case - I'm not sure what you're trying to say with your example that I haven't already said with mine. Am I missing something? –  sq33G Dec 19 '11 at 12:58
    
@sq33G: Firstly, I said you shouldn't do it. Secondly, I said if you must then I would do it the way I proposed, because it is more explicit (you don't pass a typed null value to transport the type, but a physical type value instead), more concise and very close to actually including type parameters. –  back2dos Dec 19 '11 at 13:24
    
Can you provide documentation for Class<T>? You seem to be using it like Type, but a Type that magically knows what to do with a type. –  sq33G Dec 19 '11 at 13:34
1  
@sq33G: Sorry, I can't. I was expecting C# to have something like this, since even Java has it. But upon further investigation, I surprisingly found no such thing, and if Type is the type of class objects in C#, then what I proposed is impossible. –  back2dos Dec 19 '11 at 14:23
    
I believe that even in Java, that would have to be MyDerivedClass.class. In C# there is only the semi-equivalent typeof(MyDerivedClass), but it happens not to provide the type parameter where Java does. –  sq33G Dec 20 '11 at 7:22

One thing that I think you have to be concious of being on a development "team" is that your code needs to be readable and maintainable by others. I agree with the answers to teach and move the team forward, but until that happens you need to stick with constructs that everyone understands and is comfortable with.

share|improve this answer

The gerneric parameter in your code is not "dummy", since it is used as return type. This is a common pattern also used by Microsoft in the BCL. Example found in

System.Data.DataRowExtensions

public static T Field<T>(this System.Data.DataRow row, string columnName)
share|improve this answer
    
Is this meant to be a case in point? –  sq33G Dec 18 '11 at 17:36
    
@sq33G: It is the case which first came into my mind. I am sure you will find better examples. –  Olivier Jacot-Descombes Dec 18 '11 at 17:57
    
I think you only read the first part of my code block, which was a counterexample. The example is right after that. –  sq33G Dec 18 '11 at 18:29
1  
Sorry, I thought it you were talking about a generic type parameter, but you are talking about a generic method parameter. Nevertheless, you should not use a programmatic workaround for human ignorance. Instead, send your senior programmers an email with this link: where generic type constraint –  Olivier Jacot-Descombes Dec 18 '11 at 19:34
    
where was two+ weeks ago. This week I'm just trying to add a generic method or two to the codebase without bringing about a new wave of obviously generic method calls. –  sq33G Dec 18 '11 at 19:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.