Viji
@Viji
Associate DevOps Engineer

Почему следующая программа возвращает правильное значение типа только в 3-м случае?

Почему следующая программа возвращает правильное значение (высокого уровня) типа только в 3-м случае и как еще можно вернуть тип объекта в List

using System;
using System.Collections.Generic;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        List<dynamic> idChecksList = new List<dynamic>();
        
        List<ClientViewModelNew> mappedClientsNew = new List<ClientViewModelNew>(); 
        List<ClientViewModelOld> mappedClientsOld = new List<ClientViewModelOld>();
        var obj1 = new ClientViewModelNew();
        var obj2 = new ClientViewModelOld();

        // Console.WriteLine(obj1.EXa);

        mappedClientsNew.Add(obj1);
        mappedClientsOld.Add(obj2);

        bool useNewClientObject = true; 
           
        if (useNewClientObject == true)
        {
            foreach (ClientViewModelNew item in mappedClientsNew)
            {
                idChecksList.Add(item);
            }
                
        }
        else
        {
            foreach (ClientViewModelOld item in mappedClientsOld)
            {
                idChecksList.Add(item);
            }
        }

        String typeArg0 = idChecksList.GetType().GetGenericArguments()[0].ToString(); //  GenericTypeArguments[0].ToString();
        String typeItem1 = idChecksList.GetInternalType().ToString();
        String typeItem2 = idChecksList[0].GetType().ToString();

        Console.WriteLine("internal type of List, Method 1:" + typeArg0);
        Console.WriteLine("internal type of List, Method 2:" + typeItem1);
        Console.WriteLine("internal type of List, Method 3:" + typeItem2);
    }
}

public static class GenericListExtensions
{
    public static Type GetInternalType<T>(this List<T> list)
    {
        return typeof(T);
    }
}

public class ClientViewModelNew
{
    public String EXa { get; set; } = "Initial Name for New Class";
}

public class ClientViewModelOld
{
    public String EXa { get; set; } = "Initial Name for Old Class";
}


возвращает
internal type of List, Method 1:System.Object
internal type of List, Method 2:System.Object
internal type of List, Method 3:ClientViewModelNew

Почему первые два возвращают System.Object и как это можно исправить?
  • Вопрос задан
  • 92 просмотра
Решения вопроса 1
vabka
@vabka Куратор тега .NET
Токсичный шарпист
почему первые два возвращают System.Object и как это можно исправить?

Потому-что dynamic под капотом - это на самом деле Object и куча рефлексии.
List<dynamic> - это на самом деле List<object> (можешь загнать в sharplab и убедиться в этом)

Исправить это можешь только отказавшись от dynamic (а лучше вообще забыть о его существовании. Крайне сломанная фича, которая путём говнокода позволяет в некоторых случаях сэкономить строчки)

Например, если нельзя трогать ClientViewModelNew и ClientViewModelOld, то можно попробовать так:
public interface IClientViewModel {
  public string EXa { get; set; }
}

public class ClientViewModelNewWrapper: IClientViewModel {
  private readonly ClientViewModelNew _internal;
  public ClientViewModelNewWrapper(ClientViewModelNew obj) => _internal = obj;
  public string EXa { get => _internal.EXa; set => _internal.EXa = value;}
}

public class ClientViewModelOldWrapper: IClientViewModel {
  private readonly ClientViewModelOld _internal;
  public ClientViewModelNewWrapper(ClientViewModelOld obj) => _internal = obj;
  public string EXa { get => _internal.EXa; set => _internal.EXa = value;}
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы