在通用不可用时尝试获得通用

时间:2009-05-13 16:31:54

标签: c# linq generics lambda

我正在尝试开发一些通用的自定义ValidationAttributes。一个人无法创建属性的通用子类这一事实让我疯狂。

以下是ValidationAttribute中IsValid覆盖的代码,用于验证属性的值是否唯一:

    public override bool IsValid(object value)
    {
        SomeDataContext context = SomeDataContext.GetNewDataContext();
        Type tableType = typeof(Table<>).MakeGenericType(new Type[] { _EntityType });
        var table = Activator.CreateInstance(tableType);
        //ITable table = context.GetTable(_EntityType);
        var codeProp = (from member in context.Mapping.GetMetaType(_EntityType).DataMembers
                        where member.Name == _PropertyName
                        select member.Member).Single();
        ParameterExpression param = Expression.Parameter(_EntityType, "x");
        MemberExpression memberExp = Expression.Property(param, (PropertyInfo)codeProp); 
        Expression body = Expression.Equal(memberExp, Expression.Constant(value, typeof(char)));
        //var predicate = Expression.Lambda<Func<TEntityType, bool>>(body, param);
        Type lambdaType = typeof(Func<,>).MakeGenericType(_EntityType, typeof(bool));
        var predicate = Expression.Lambda(lambdaType, body, param);
        object code = table.FirstOrDefault(predicate);
        if (code != null)
        {
            return false;
        }
        return true;
    }

这一行:

object code = table.FirstOrDefault(predicate);

出错:

'object'不包含'FirstOrDefault'的定义,也没有扩展......等等。

如何定义,强制转换或以其他方式让编译器将“table”识别为暴露.FirstOrDefault方法的东西?

由于

2 个答案:

答案 0 :(得分:2)

  

如何定义,强制转换或以其他方式让编译器将“table”识别为暴露.FirstOrDefault方法的东西?

通过对某事物的IEnumerable<>使用显式强制转换。由于您不了解案例中的“某些内容”,因此您实际上无法使用FirstOrDefault。只需自己实现逻辑:

var enumerator = ((IEnumerable)table).GetEnumerator();
object code = enumerator.MoveNext() ? enumerator.Value : null;

答案 1 :(得分:2)

这将使您获得System.Linq.Enumerable可以使用的类型:

IEnumerable<object> tableGeneric =
  ((IEnumerable)table).OfType<object>();

三个问题:

  1. 不要使用var这么多 - 你会忘记你的类型。
  2. 我不确定在FirstOrDefault调用中使用谓词 - 我没有看到编译器如何键入检查它。 http://msdn.microsoft.com/en-us/library/bb299425.aspx
  3. 如果你使谓词有效,.Any()可能是比.FirstOrDefault()
  4. 更好的选择。