Es posible limitar un método para que los registros sólo?

0

Pregunta

Vamos a asumir que tengo varios record-tipos con una interfaz común, de la siguiente manera:

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; }
}

Mi objetivo es escribir una función para actualizar la Etiqueta de registro de la propiedad a través de clonation.

Ahora, si el tipo se sabe, yo podría escribir algo como esto:

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

Sin embargo, me gustaría evitar a escribir un montón de sobrecargas, así que me pregunto si hay un modo más genérico para lograr eso. Por ejemplo, yo estaría tentado de escribir como:

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

pero eso no va a compilar, porque TRec podría ser cualquier cosa (class, struct, etc), no sólo un record donde puedo usar el with declaración. Por el camino, no hay un record-restricción de que yo pueda aplicar.

Así que, ¿hay alguna solución? es algo que esperan ser resueltos en el futuro?

Como una pregunta extra (sólo para el bien de la curiosidad), ¿por qué un record-traducido de la clase no está marcado con una interfaz especial, con el fin de hacer el with instrucción de trabajo contra?

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

Mejor respuesta

1

En lugar de tener un vacío de la base de registro, tienen todos estos registros heredar de una base común de registro, que implementa la interfaz:

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

De acuerdo, se ve mejor!
Mario Vernari

En mi humilde opinión, no sólo se ve mejor, pero en realidad es mejor - no sólo no está utilizando un "marcador", que es un código de olor, en realidad se está utilizando la herencia de la manera que debe ser utilizado.
Zohar Peled
0

Gracias a otra respuesta (ver el enlace en los comentarios), parece ser un chapucero solución:

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 };
}

La restricción es eficaz debido a la R registro, mientras que el Tag asignación gracias a la init descriptor de acceso.

De nuevo, para mí es como un hack que una solución real. Prefiero ver a algunos nativos de apoyo.

2021-11-20 06:57:32

En otros idiomas

Esta página está en otros idiomas

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