Je možné omezit metodu pro záznamy pouze?

0

Otázka

Předpokládejme, že mám několik různých record-typy se společným rozhraním, a to následovně:

record Rec1(
    string Tag
    ) : IFoo;

record Rec2(
    int Num,
    string Tag
    ) : IFoo;

record Rec3(
    bool Flag
    ) : IFoo
{
    public string Tag { get; init; }
    public double Value { get; init; }
}

// ... others ...

interface IFoo
{
    string Tag { get; }
}

Mým cílem je napsat funkci pro aktualizaci Tag majetku prostřednictvím záznamu clonation.

Nyní, pokud typ byl známý, mohl bych napsat něco jako toto:

    private Rec2 Update(Rec2 rec, string tag)
    {
        return rec with { Tag = tag };
    }

Nicméně, já bych se zabránilo napsat pár přetížení, takže jsem přemýšlel, jestli tam je více obecný způsob, jak dosáhnout, že. Například bych v pokušení napsat jako:

    private TRec Update<TRec>(TRec rec, string tag) where TRec : IFoo
    {
        return rec with { Tag = tag };
    }

ale to nezkompiluje, protože TRec mohlo by to být cokoliv (class, structatd.), ne jen record kde mohu použít with prohlášení. Mimochodem, tam je ne record-omezení, které bych mohl použít.

Takže, je tam nějaké řešení? je to něco očekávat, že bude vyřešena v budoucnosti?

Jako bonus otázku (jen pro čistě ze zvědavosti), proč record-přeloženo třída není označena speciální rozhraní, aby with prohlášení proti?

c# constraints generics record
2021-11-20 05:42:41
2

Nejlepší odpověď

1

Místo toho prázdnou základnu záznam, mít všechny tyto záznamy dědit od společné základny záznam, který implementuje vaše rozhraní:

record R : IFoo ...

record Rec1 : R....
record Rec2 : R....

private TRec Update<TRec>(TRec rec, string tag) where TRec : R
{
    return rec with { Tag = tag };
}
2021-11-20 07:03:58

Souhlasím, vypadá lépe!
Mario Vernari

IMHO, nejen vypadá lépe, ale ve skutečnosti je lepší - nejen, že nepoužíváte "marker", což je kód, vůně, jste ve skutečnosti pomocí dědičnosti tak, jak by měl být použit.
Zohar Peled
0

Díky jinou odpověď (viz odkaz v komentářích), zdá se být hraví řešení:

record R();

record Rec1(
    string Tag
    ) : R, IFoo;

// ... others ...

interface IFoo
{
    string Tag { get; init; }
}

private TRec Update<TRec>(TRec rec, string tag) where TRec : R, IFoo
{
    return rec with { Tag = tag };
}

Omezení je efektivní vzhledem k R záznam, zatímco Tag úkol díky init accessor.

Znovu, pro mě je podobně jako hack, než skutečné řešení. Já bych raději vidět některé nativní podporu.

2021-11-20 06:57:32

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................