2

ドメインモデルで使用されるカスタムLocalizedStringタイプがあります。のような検証属性でプロパティを装飾したいと思いますMaxLength。このために、この属性に必要なキャストを有効にする暗黙の演算子を追加しました。

IsValid不思議なことに、演算子が呼び出されることはなく、属性メソッドでInvalidCastExceptionがスローされるようです。私たち自身のプロジェクトでこのキャストを実行することはうまくいきます。

このシステムのclrngen'ed属性などで、特別なキャスト動作コンパイラマジックが実行されていますか?

// 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.
4

2 に答える 2

9

あらゆる種類の演算子は、コンパイル時にオブジェクトのタイプがわかっている場合にのみ適用されます。それらは「オンザフライ」でに適用されません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!)
    }
}
于 2012-06-13T22:23:42.997 に答える
1

あなたが書く

((Array) value)

ただし、静的な値のタイプはオブジェクトです。したがって、これはオブジェクトから配列へのキャストとしてコンパイルされます。変換演算子は考慮されません。

これをに変更します

((Array)(value as LocalizedString))

そして、あなたは大丈夫でしょう。

于 2012-06-13T22:27:16.167 に答える