views:

146

answers:

2

I have a class MyClass with a method:

public bool MyMethod(out DateTime? MyDate) {
  ...
}

I'd like to call this method in the following way:

var q = from mc in MyClasses.AsEnumerable()
        from output in mc.MyMethod(out dt) // how to declare dt?
        select new { mc, output, dt };

Obviously this doesn't compile, coz I haven't declared dt. I can declare it outside the query, but that doesn't give me a warm fuzzy feeling: (a) I don't like declaring variables at a level greater than the necessary scope, and (b) it isn't immediately and intuitively obvious that the value would be calculated correctly for each row inside the query.

Is there some syntax that will allow me to declare DateTime? dt inside the query?

+5  A: 

My first thought is "ew" (thats my code smell noise). I feel you're really trying to force using that method where it doesn't belong.

My next thought would be to simply create the behavior you want, maybe something such as (although I still don't recommend this as a good solution):

public DateTime? GetMyDate() 
{
   DateTime? dt;
   MyMethod(out dt);
   return dt;
}

Then...

var q = from mc in MyClasses.AsEnumerable()
        select new { mc, output, Date = GetMyDate() };

I'm making the assumption that the bool returned from MyDate isn't important in this context, which really breaks intent. I only assume that because, given your desired result, you don't seem to care about the bool return either.

In either case, I would recommend rethinking this instead of making due with what you have.

Marc
Well, the "ew" comment is funny enough, but why do you dismiss out of hand the possibility that I might need both "output" and MyDate? In fact, in my "real" code, the output of MyMethod is the thing I'm most interested in (it means is the thing valid), and the datetime is an expiry date (until when is it valid). Both values have intrinsic and important meaning.
Shaul
I dismiss it because in your example usage, you do. I'm not implying it may not satisfy some need somewhere else, simply not here. It appears that your desire is reuse. Being that as it may, my recommendation, not looking at your source, is to extract the underlying logic that populates your out DateTime and calling *that* here (and in your MyDate(..) function). Sorry, I didn't mean to imply that it wasn't useful in another context.
Marc
Ahh, in retrospect, I see now how you're attempting to use the output. Sorry, the syntax totally threw me off. +1 to Tim for catching it and providing usable solution.
Marc
+6  A: 

Its not just the scope of dt that is the problem here, your MyMethod() would need to return an enumeration for the SelectMany to work (the second from clause)

Not really sure what you are trying to achieve here but I would be inclined to have your function return a struct or class that contains the bool and the date and assign it via a let statement...something like...

var qry = from mc in MyClasses.FunctThatReturnsAnIEnumerable()
          let result = mc.MyMethod() //this returns the struct
          select new {mc, result.BoolVal, result.DateVal};
Tim Jarvis
+1 Now THAT's a good idea. See my comment to @Marc's answer; both values do have meaning and importance, so perhaps it would be right to put them in a class of their own.
Shaul