Попытка получить универсальный, когда универсальный недоступен - PullRequest
2 голосов
/ 13 мая 2009

Я пытаюсь разработать пользовательские атрибуты общего назначения ValidationAttributes. Тот факт, что невозможно создать общий подкласс атрибута, сводит меня с ума.

Вот мой код для переопределения IsValid в атрибуте ValidationAttribute для проверки уникальности значения свойства:

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

Эта строка:

код объекта = table.FirstOrDefault (предикат);

ошибок:

'объект' не содержит определения для 'FirstOrDefault' и не имеет расширения ...... и т. Д.

Как определить, привести или иным образом заставить компилятор распознавать «таблицу» как нечто, открывающее метод .FirstOrDefault?

Спасибо

Ответы [ 2 ]

2 голосов
/ 13 мая 2009

Это приведет вас к типу, который 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 ()
2 голосов
/ 13 мая 2009

Как определить, привести или иным образом заставить компилятор распознавать «таблицу» как нечто, открывающее метод .FirstOrDefault?

Используя явное приведение к IEnumerable<> чего-либо. Поскольку вы не знаете «что-то» в вашем случае, вы фактически не можете использовать FirstOrDefault. Просто реализуйте логику самостоятельно:

var enumerator = ((IEnumerable)table).GetEnumerator();
object code = enumerator.MoveNext() ? enumerator.Value : null;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...