implicit/explicit conversion operator not called by attribute (System.ComponentModel.DataAnnotation.dll)
c#, data-annotations, explicit-conversion, implicit-conversion
Solution
Operators of any kind only apply if the type of object is known at compile time. They are not applied "on the fly" to `object`.
You could try using `dynamic` which does do that.
Examples:
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!)
}
}
Problem
We have a custom LocalizedString type used in our domain model. We want to decorate the properties with validation attributes like `MaxLength`. For this, we added implicit operators to enable casts required by this attribute. Strangely, the operator seems to never get called and an InvalidCastException get's thrown in the attributes `IsValid` method. Performing this cast in our own project works. Is there a special cast behavior compiler magix going on in this system clr ngen'ed attribute or something? ``` // 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); } ``` Thanks for your help. Edit ``` 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. ```