Is it possible to use general constraints based on attributes rather than types?

I am trying to write a class that will be responsible for persisting application variations. Since the parameters must be saved, the values ​​that I submit must be serialized.

Initially, I thought I could write a method with this signature:

Public Sub SaveOption(Of T As ISerializable)(ByVal id As String, ByVal value As T)

or if you prefer C #:

public void SaveOption<T>(string id, T value) where T : ISerializable  

That would be nice in principle, but what about types that have an attribute <Serializable>? The most noteworthy example of this is System.String, it does not implement ISerializable, but obviously this is the type I have to keep.

So, is there a way that I can limit which types are allowed in a method in compiletime, based on their attributes?

+3
4

- :

public void SaveOption(string id, string value)

; ... ; , .

+2

, , , .

[Serializable] - , , ISerializable , , GetObjectData, , .

,

[Serializable]
class GoodClass
{
    public object Property { get; set; }
}

class BadClass
{
}

GoodClass BadClass,

MemoryStream ms = new MemoryStream();
BinaryFormatter f = new BinaryFormatter();

GoodClass obj = new GoodClass();
f.Serialize(ms, obj); // OK

obj.Property = new BadClass();
f.Serialize(ms, obj); // BOOM

EDIT: , , , , :

class NotSoGoodClass : GoodClass // No [Serializable] attribute
{
}

...

SaveOption<GoodClass>( "id", new NotSoGoodClass() ) // oops
+2

.: (

, , # 4.0 . .

: CLR 4.0:

public void BuyMoreStuff(Item[] cart, ref Decimal totalCost, Item i)
{       
    CodeContract.Requires(totalCost >=0);
    CodeContract.Requires(cart != null);
    CodeContract.Requires(CodeContract.ForAll(cart, s => s != i));

    CodeContract.Ensures(CodeContract.Exists(cart, s => s == i);
    CodeContract.Ensures(totalCost >= CodeContract.OldValue(totalCost));
    CodeContract.EnsuresOnThrow<IOException>(totalCost == CodeContract.OldValue(totalCost));

    // Do some stuff
}
+1

, , , , .

public static byte[] SerializeObject<T>(this T obj)
{
    Contract.Requires(typeof(T).IsSerializable);
    ...
}
0

Source: https://habr.com/ru/post/1716301/


All Articles