Оператор неявного / явного преобразования не вызывается атрибутом (System.ComponentModel.DataAnnotation.dll)
У нас есть собственный тип LocalizedString, используемый в нашей модели предметной области. Мы хотим украсить свойства с атрибутами проверки, такими как MaxLength
, Для этого мы добавили неявные операторы для включения приведений, требуемых этим атрибутом.
Странно, что оператор, кажется, никогда не вызывается, и InvalidCastException get добавляется в атрибуты IsValid
метод. Выполняя этот актерский состав в нашем собственном проекте работ.
Есть ли в этом системном атрибуте clr ngen'а специальная магия компилятора поведения приведения?
// Custom type
public class LocalizedString
{
public string Value
{
get { return string.Empty; }
}
public static implicit operator Array(LocalizedString localizedString)
{
if (localizedString.Value == null)
{
return new char[0];
}
return localizedString.Value.ToCharArray();
}
}
// Type: System.ComponentModel.DataAnnotations.MaxLengthAttribute
// Assembly: System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.ComponentModel.DataAnnotations.dll
public override bool IsValid(object value)
{
this.EnsureLegalLengths();
if (value == null)
{
return true;
}
else
{
string str = value as string;
int num = str == null ? ((Array) value).Length : str.Length;
if (-1 != this.Length)
return num <= this.Length;
else
return true;
}
}
[TestMethod]
public void CanCallIsValidWithLocalizedString()
{
// Arrange
var attribute = new MaxLengthAttribute(20);
var localized = new LocalizedString { Value = "123456789012345678901" };
// Act
var valid = attribute.IsValid(localized);
// Assert
Assert.IsFalse(valid);
}
Спасибо за вашу помощь.
редактировать
Das Objekt des Typs "Nexplore.ReSearch.Base.Core.Domain.Model.LocalizedString" kann nicht in Typ "System.Array" umgewandelt werden.
bei System.ComponentModel.DataAnnotations.MaxLengthAttribute.IsValid(Object value)
bei Nexplore.ReSearch.Base.Tests.Unit.Infrastructure.CodeFirst.MaxLengthLocalizedAttributeTests.CanCallIsValidWithLocalizedString() in d:\Nexplore\SourceForge\Nexplore.ReSearch.Base\Source\Nexplore.ReSearch.Base.Tests.Unit\Infrastructure.CodeFirst\MaxLengthLocalizedAttributeTests.cs:Zeile 40.
2 ответа
Операторы любого типа применяются, только если тип объекта известен во время компиляции. Они не применяются "на лету" для object
,
Вы можете попробовать использовать dynamic
который делает это.
Примеры:
using System;
class Foo
{
public static implicit operator Array(Foo foo)
{
return new int[0]; // doesn't matter
}
static void Main()
{
Foo foo = new Foo();
Array x = (Array)foo; // implicit operator called via compiler
dynamic dyn = foo;
Array y = (Array)dyn; // implicit operator called via dynmic
object obj = foo;
Array z = (Array)obj; // implicit operator NOT called
// - this is a type-check (BOOM!)
}
}
Ты пишешь
((Array) value)
Но статическим типом значения является объект. Так что это скомпилировано как приведение от объекта к массиву. Ваш оператор преобразования даже не рассматривается.
Изменить это на
((Array)(value as LocalizedString))
и у тебя все будет хорошо.