Dedurre automaticamente il tipo di ritorno dai vincoli

Luca Iovene 0 Punti di reputazione
2024-04-16T08:11:30.0733333+00:00

Io vorrei rendere più facile possibile l'uso del mio metodo senza dover specificare i tipi esplicitamente.

Per farlo mi sono creato la seguente struttura:

public interface IConvertible<T>
{
    public T ConvertInstance();
}
public class User : IConvertible<UserDTO> 
{
	public string Name { get; set; }
	public string Surname { get; set; }

	public UserDTO ConvertInstance()
	{
		//manage to convert from user to userDTO
		return dto;
	}
}
public class UserDTO
{
	public string Name { get; set; }
	public string Surname { get; set; }
}

E infine ho un metodo in una classe separata che ha la seguente firma:

public async Task<List<Tdto>> ExecuteExpression<Tentity,Tdto>(Expression<Func<Tentity, bool>> expression, params Expression<Func<Tentity, object>>[] includes) where Tentity : class, IConvertible<Tdto> where Tdto : class 
{
	//manage to take from database object of type Tentity
	List<Tdto> convertedItems = new();
	foreach (var item in items) 
	{
		var converted = item.ConvertInstance();
		convertedItems.add(converted);
	}
}

La mia domanda è la seguente:

Come posso fare in modo che quando chiamo il metodo ExecuteExpression io non debba specificare i tipi del metodo ma li capisca da solo?

Il tipo Tentity lo capisce già da solo in quanto viene passato all'interno della Expression<Func<Tentity, bool>> mi manca da far capire al compilatore la relazione tra Tentity e Tdto.

Qualcuno può darmi una mano?

C#
C#
Un linguaggio di programmazione orientato agli oggetti e indipendente dai tipi che ha le sue radici nella famiglia di linguaggi C e include il supporto per la programmazione orientata ai componenti.
2 domande
0 commenti Nessun commento
{count} voti

2 risposte

Ordina per: Più utili
  1. Yordan Ivanov 385 Punti di reputazione
    2024-04-16T10:32:48.0133333+00:00

    Buongiorno, Luca,

    Non devi preoccuparti di recuperare gli argomenti e chiamare tu stesso MethodInfo, puoi lasciare che .NET lo faccia per te. Tutto quello che devi fare è creare un'espressione Lambda contenente quel metodo.

    MethodCallExpression expression = GetExpressionSomeHow();
    object result = Expression.Lambda(expression).Compile().DynamicInvoke();
    

    È così che gestisco comunque le query nidificate nel mio provider Linq.

    In caso tu abbia una LambdaExpression nella variabile del selettore, potresti semplicemente compilarla e invocarla direttamente:

    object result = selector.Compile().DynamicInvoke();
    

    Spero che questa informazione aiuta nel tuo caso.

    0 commenti Nessun commento

  2. Luca Iovene 0 Punti di reputazione
    2024-04-16T13:12:39.9333333+00:00

    Forse mi sono spiegato male:

    io vorrei che quando chiamo il metodo in questione io possa scrivere direttamente

    var result = await _repository.ExecuteExpression(expression, ...);
    

    Invece attualmente io devo specificare anche i tipi del metodo nel seguente modo:

    var result = await _repository.ExecuteExpression<User,UserDTO>(expression, ...);
    

    Il primo tipo il compilatore lo deduce automaticamente in quanto è contenuto nel tipo dell'expression che è di tipo Expression<Func<User, bool>> ma come faccio invece per il secondo tipo ossia UserDTO.
    Loro in teoria sono legati in quanto la classe User implementa l'interfaccia IConvertible<UserDTO>.