当通用不可用时尝试获取通用

发布于 2024-07-20 06:03:45 字数 1578 浏览 3 评论 0原文

我正在尝试开发一些通用的自定义 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”的定义,并且没有扩展名......等。

如何定义、转换或以其他方式让编译器将“表”识别为公开 .FirstOrDefault 方法的内容?

谢谢

I am trying to develop some general purpose custom ValidationAttributes. The fact that one cannot create a generic subclass of an attribute is making me nuts.

Here is my code for the IsValid override in a ValidationAttribute to verify that the value of a property is unique:

    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;
    }

This line:

object code = table.FirstOrDefault(predicate);

errors out:

'object' does not contain a definition for 'FirstOrDefault' and no extension ......etc.

How do I define, cast or otherwise get the compiler to recognize "table" as something that exposes a .FirstOrDefault method?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴情 2024-07-27 06:03:45

这将使您获得 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() 更好的选择

This will get you to a type that System.Linq.Enumerable can use:

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

Three concerns:

  1. Don't use var so much - you'll lose track of your types.
  2. I'm unsure about using your predicate in a FirstOrDefault call - I don't see how the compiler can type check it. http://msdn.microsoft.com/en-us/library/bb299425.aspx
  3. If you get the predicate working, .Any() might be a better choice than .FirstOrDefault()
明媚殇 2024-07-27 06:03:45

如何定义、转换或以其他方式让编译器将“表”识别为公开 .FirstOrDefault 方法的内容?

通过使用显式转换为某些内容的 IEnumerable。 由于您不知道您的情况中的“某些内容”,因此您实际上无法使用 FirstOrDefault。 自己简单实现一下逻辑:

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

How do I define, cast or otherwise get the compiler to recognize "table" as something that exposes a .FirstOrDefault method?

By using an explicit cast to IEnumerable<> of something. Since you don't know the “something” in your case, you effectively cannot use FirstOrDefault. Simply implement the logic yourself:

var enumerator = ((IEnumerable)table).GetEnumerator();
object code = enumerator.MoveNext() ? enumerator.Value : null;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文