I have never done this before, and while I can't think of a specific reason that it would break, I'd like to verify that it is valid to use an out variable as follows:
void Main()
{
var types = new [] { typeof(A), typeof(B) };
bool b = false;
var q = from type in types
from property in type.GetProperties()
let propertyName = GetName(property, out b)
select new {
TypeName = type.Name,
PropertyName = propertyName,
PropertyType = property.PropertyType.Name,
IsNullable = b
};
q.Dump();
}
private string GetName(PropertyInfo property, out bool isNullable)
{
string typeName;
isNullable = false;
var type = property.PropertyType;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
isNullable = true;
typeName = type.GetGenericArguments().First().Name;
}
else
{
typeName = property.Name;
}
return typeName;
}
This will work - provided you actually fully evaluate the query.
However, the behavior will be very odd, and would be something I would strongly avoid. Since the out parameter is being used directly within the query, the behavior will be fairly normal here (provided you don't do anything else with this), but that is specific to this use case, not a general "rule" with using out mixed with LINQ.
The problem is that LINQ's deferred execution will cause the out parameter to get set, but only when you use the resulting enumerable, not when you declare it. This can cause very unexpected behavior, and lead to difficult to maintain and understand software.
I would personally just write a separate method, and use it to allow your query to be written as:
var q = from type in types
from property in type.GetProperties()
let propertyName = GetName(property)
let nullable = GetIsNullable(property)
// ...
This is much more clear, and less prone to mistakes and errors. It will also work with parallelization (ie: PLINQ via .AsParallel()
) and other techniques if somebody tries to change this later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With