Is it safe to use variables in calls in LINQ statements?

I have never done this before, and while I can’t think of any specific reason that it will break, I would like to verify that the following is true for using the out variable:

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;
}
+5
source share
3 answers

This will work - if you really fully appreciate the request.

However, the behavior will be very strange, and I would greatly avoid it. Since the out parameter is used directly in the request, the behavior here will be quite normal (if you do not do anything with it), but this is specific to this use case, and not to the general "rule" using mixed with LINQ.

, LINQ , out , , . .

, :

var q = from type in types 
        from property in type.GetProperties() 
        let propertyName = GetName(property)
        let nullable = GetIsNullable(property)
        // ...

. (, PLINQ .AsParallel()) , - .

+10

, , , , . , , , , .

GetName , . , false ( , # ). , b . , , b .

. , .

+3

This will work roughly , but for any wrong reason (and it’s a bad habit to pick, since it is unsafe in a more general case). A safer idea is a tuple:

        let info = GetInfo(property)
        select new {
            TypeName = type.Name,
            PropertyName = info.Item1,
            PropertyType = property.PropertyType.Name,
            IsNullable = info.Item2
        };

....

private Tuple<string,bool> GetInfo(PropertyInfo property)
{
    string typeName;
    bool isNullable = false;
    ...
    return Tuple.Create(typeName, isNullable);
}

For more complex scenarios, a type with reasonably named properties would be even better.

+3
source

All Articles