Neden "ondalık" geçerli bir özellik parametre türü değil?


139

Gerçekten inanılmaz ama gerçek. Bu kod çalışmaz:

[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
    public decimal Max { get; set; }
    public decimal Min { get; set; }
}

public class Item
{
    [Range(Min=0m,Max=1000m)]  //compile error:'Min' is not a valid named attribute argument because it is not a valid attribute parameter type 
    public decimal Total { get; set; }  
}

Bu çalışırken:

[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
    public double Max { get; set; }
    public double Min { get; set; }
}

public class Item
{
    [Range(Min=0d,Max=1000d)]
    public decimal Total { get; set; }  
}

Ondalık yokken neden çiftin iyi olduğunu kim söyleyebilir?


Yanıtlar:


139

Bu bir CLR kısıtlamasıdır. Nitelik parametreleri olarak yalnızca ilkel sabitler veya ilkel dizileri kullanılabilir. Bunun nedeni, bir özelliğin tamamen meta verilerde kodlanması gerektiğidir. Bu, IL'de kodlanmış bir yöntem gövdesinden farklıdır. MetaData kullanmak, kullanılabilecek değerlerin kapsamını ciddi şekilde kısıtlar. CLR'nin mevcut sürümünde, meta veri değerleri ilkel, boş, ilkel tür ve dizileri ile sınırlıdır (küçük bir veriyi kaçırmış olabilir).

Alındığı bu tarafından cevap JaredPar .

Temel bir türken ondalık sayılar ilkel bir tür değildir ve bu nedenle öznitelik parametresi olmasını engelleyen meta verilerde temsil edilemez.


35
Neden ondalık sayılar CLR'de ilkel tip olarak kabul edilmez?
koumides

10
@koumides Cevabın 128bit olduğu için tek bir CPU kaydında ifade etmek için çok büyük olduğuna inanıyorum
Chris Marisic

2
Peki neden dizelere öznitelik özellikleri olarak izin veriliyor? Sanırım 'ilkel dizi' kategorisi altında geliyor ama yığın ayrılmış (referans türü) ...
Steztric

Çünkü dizeler tamamen farklı işlenen referans türleridir.
Carsten Schütte

2
@Soren bu doğru değil Enum, destekleniyor. Şu anda 2 enum ve diğer bir dizi ile 2 özel öznitelikleri var.
Franck

60

Teknik özelliklerden :

Bir öznitelik sınıfı için konumsal ve adlandırılmış parametre türleri, öznitelik parametresi türleriyle sınırlıdır:

  • Aşağıdaki türlerden biri: bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
  • Türü object.
  • Türü System.Type.
  • Bir enum türü, genel erişilebilirliğe ve iç içe yerleştirildiği türlere (varsa) genel erişilebilirliğe sahip olması koşuluyla (Öznitelik belirtimi).
  • Yukarıdaki tiplerin tek boyutlu dizileri.

10
Doğru, ancak spesifikasyonun eski bir sürümünü alıntıladığınızı unutmayın. C # sürüm 3.0, 4.0, ve 5.0, bu aynı zamanda türü olabilir belirtilmektedir sbyte, ushort, uint, ulong. Ve bu iyi çalışıyor gibi görünüyor. Ama yine decimalde izin verilmiyor :-(
Jeppe Stig Nielsen

1
@JeppeStigNielsen Spesifikasyon bağlantısını ve fiyat teklifini güncelledim
Ohad Schneider

6
Null olabilecek ilkeller de DESTEKLENMEZ.
KTCO

2

Bu sorunun cevabı, atom tipi olmamasına rağmen nitelik olarak izin verilen dizeleri kullanmaktır. Yuvarlama sonuçları daha az doğru hale getireceğinden çiftleri kullanmayın.

public String MinimumValue
{
    get
    {
        return minimumValueDecimal.ToString();
    }

    set
    {
        minimumValueDecimal = Decimal.Parse(value);
    }
}

private decimal minimumValueDecimal;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.