Как я могу создать общий метод возвратить определенный тип, указанный вызовом?

Следующий код дает мне ошибки:

Cannot implicitly convert type T to string.
Cannot implicitly convert type T to int.

Что я должен сделать, чтобы заставить этот метод возвращать тип переменной, которую я определяю с T, когда я называю его?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestGener234
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("his first name is {0}", GetPropertyValue<string>("firstName"));
            Console.WriteLine("his age is {0}", GetPropertyValue<int>("age"));
        }

        public static T GetPropertyValue<T>(string propertyIdCode)
        {
            if (propertyIdCode == "firstName")
                return "Jim";
            if (propertyIdCode == "age")
                return 32;
            return null;
        }
    }
}

Приложение:

Вот более полный пример того, почему мне было нужно универсальное решение, т.е. у Меня есть класс, который сохраняет его значения как строки независимо от того, что тип и это универсальное решение просто делают инструментом для очистки кода вызова:

using System;
using System.Collections.Generic;

namespace TestGener234
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Item> items = Item.GetItems();
            foreach (var item in items)
            {
                string firstName = item.GetPropertyValue<string>("firstName");
                int age = item.GetPropertyValue<int>("age");
                Console.WriteLine("First name is {0} and age is {1}.", firstName, age);
            }
            Console.ReadLine();
        }
    }

    public class Item
    {
        public string FirstName { get; set; }
        public string Age { get; set; }


        public static List<Item> GetItems()
        {
            List<Item> items = new List<Item>();
            items.Add(new Item { FirstName = "Jim", Age = "34" });
            items.Add(new Item { FirstName = "Angie", Age = "32" });
            return items;
        }

        public T GetPropertyValue<T>(string propertyIdCode)
        {
            if (propertyIdCode == "firstName")
                return (T)(object)FirstName;
            if (propertyIdCode == "age")
                return (T)(object)(Convert.ToInt32(Age));
            return default(T);
        }
    }
}
5
задан Edward Tanguay 29 January 2010 в 13:46
поделиться

8 ответов

, который является неприятным; Чтобы сделать компилятор счастливым, вы можете дважды отличить, но это подразумевает коробку для типов значений:

    public static T GetPropertyValue<T>(string propertyIdCode)
    {
        if (propertyIdCode == "firstName")
            return (T)(object)"Jim";
        if (propertyIdCode == "age")
            return (T)(object)32;
        return default(T);
    }

На самом деле, я думаю, вы можете быть лучше, просто используя объект Тип возврата.

13
ответ дан 18 December 2019 в 07:09
поделиться
    public static T GetPropertyValue<T>(string propertyIdCode)
    {
        object result = null;
        if (propertyIdCode == "firstName")
            result = "Jim";
        if (propertyIdCode == "age")
            result = 32;
        return result == null ? default(T) : (T)result;
    }
0
ответ дан 18 December 2019 в 07:09
поделиться

Пример двойного литья MARC является правильным способом, чтобы сделать компилятор, чтобы вести себя правильно.

Вы можете написать спетель для каждого типа значения и иметь универсальный метод для контрольных типов. Это прекратит остановить бокс на типов значений.

Это полезно только в том случае, если доступ к объектам не входит в систему для хранения (например, не сохраняется как объект).

public static T GetPropertyValue<T>(string propertyIdCode)
{
}

public static int GetPropertyInt(string propertyIdCode)
{
}
0
ответ дан 18 December 2019 в 07:09
поделиться

Это должно работать ...

  public static T GetPropertyValue<T>(string propertyIdCode)
  {
     if (propertyIdCode == "firstName")
        return (T)Convert.ChangeType("Jim", typeof(T));
     if (propertyIdCode == "age")
        return (T)Convert.ChangeType(22, typeof(T));
     return default(T);
  }
2
ответ дан 18 December 2019 в 07:09
поделиться

Это злоупотребление дженериками. Если у вас есть небольшое количество типов, что параметр «Общий тип» может быть, просто заменить его с помощью многих способов:

string GetTextProperty(string propertyName) { ... }
int GetNumberProperty(string propertyName) { ... }
Giraffe GetGiraffeProperty(string propertyName) { ... }
4
ответ дан 18 December 2019 в 07:09
поделиться

Обычно, когда вы отличаете в общий метод, это проблема дизайна. Обычно вы хотите сохранить свой тип в вашем методе внутри вашего метода ( без литья, без пробки на основе типа ), что-то подобное:

public class Properties<T>
{
    private Dictionary<string, T> _dict = new Dictionary<string, T>();

    public void SetPropertyValue<T>(string propertyIdCode, T value)
    {
        _dict[propertyIdCode] = value;
    }

    public T GetPropertyValue<T>(string propertyIdCode)
    {
        return _dict[propertyIdCode];
    }
}

, другой рукой, если вы Хотите получить доступ к свойствам объекта через их имя (похоже, что это то, что вы делаете, извините, если я ошибся к нему), правильный путь будет использовать отражение ( PropertyInfo.getValue ):

public object GetPropertyValue(object obj, string propertyIdCode)
{
    PropertyInfo pinfo = obj.GetType().GetProperty(propertyIdCode);
    return pinfo.GetValue(obj, null);
}
1
ответ дан 18 December 2019 в 07:09
поделиться

GetPropertyValue («Age») хочет вернуть строку. Измените его на GetPropertyValue («возраст») , и он будет работать до тех пор, пока «возраст» - это ваше значение параметра.

Ваша реализация будет лучше получить тип универсального параметра t для того, чтобы выбрать, что для возврата вместо того, чтобы насаживать его на параметре функций.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestGener234
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("his first name is {0}", GetPropertyValue<string>("firstName"));
            Console.WriteLine("his age is {0}", GetPropertyValue<int>("age"));
        }

        public static T GetPropertyValue<T>(string propertyIdCode)
        {
            if (typeof(T) == typeof(string) && propertyIdCode == "firstName")
                return "Jim";
            if (typeof(T) == typeof(string) && propertyIdCode == "age")
                return "32";
            if (typeof(T) == typeof(int) && propertyIdCode == "age")
                return 32;
            throw (new ArgumentException());
        }
    }
}
1
ответ дан 18 December 2019 в 07:09
поделиться

Вы можете вернуть объект из GetPropertyValue, а затем сделать актеры. Вы пытаетесь использовать универсальный метод для возврата определенных типов в зависимости от входных параметров. Звучит с толку: -)

public static object GetPropertyValue(string propertyIdCode)
    {
        if (propertyIdCode == "firstName")
            return "Jim";
        if (propertyIdCode == "age")
            return 32;
        return null;
    }

, а затем набрал (INT) GetPropertyValue («возраст»);

1
ответ дан 18 December 2019 в 07:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: