Подтвердить что ты не робот

Общий метод Выполняется со временем выполнения

У меня есть следующий код:

 public class ClassExample
{

    void DoSomthing<T>(string name, T value)
    {
        SendToDatabase(name, value);
    }

    public class ParameterType
    {
        public readonly string Name;
        public readonly Type DisplayType;
        public readonly string Value;

        public ParameterType(string name, Type type, string value)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");
            if (type == null)
                throw new ArgumentNullException("type");

            this.Name = name;
            this.DisplayType = type;
            this.Value = value;
        }
    }

    public void GetTypes()
    {
        List<ParameterType> l = report.GetParameterTypes();

        foreach (ParameterType p in l)
        {
            DoSomthing<p.DisplayType>(p.Name, (p.DisplayType)p.Value);
        }

    }
}

Теперь я знаю, что не могу выполнять DoSomething() есть ли другой способ использовать эту функцию?

4b9b3361

Ответ 1

Вы можете, но это связано с отражением, но вы можете это сделать.

typeof(ClassExample)
    .GetMethod("DoSomething")
    .MakeGenericMethod(p.DisplayType)
    .Invoke(this, new object[] { p.Name, p.Value });

Это будет выглядеть в верхней части содержащего класса, получить информацию о методе, создать общий метод с соответствующим типом, затем вы можете вызвать Invoke на нем.

Ответ 2

this.GetType().GetMethod("DoSomething").MakeGenericMethod(p.Value.GetType()).Invoke(this, new object[]{p.Name, p.Value});

Должен работать.

Ответ 3

Типы родов не могут быть указаны во время выполнения так, как вы хотели бы здесь.

Простейшими параметрами были бы добавление неосновной перегрузки DoSomething или просто вызов DoSomething<object> и игнорирование p.DisplayType. Если SendToDatabase зависит от типа времени компиляции value (и это, вероятно, не должно), не должно быть ничего плохого в предоставлении ему object.

Если вы не можете это сделать, вам нужно будет вызвать DoSomething с помощью отражения, и вы получите большой успех.

Ответ 4

Сначала нам нужно преобразовать p.Value в нужный тип, так как даже если мы знаем тип во время компиляции, мы не можем передать строку прямо к методу...

DoSomething<Int32>( "10" ); // Build error

Для простых числовых типов и DateTime мы можем использовать

object convertedValue = Convert.ChangeType(p.Value, p.DisplayType);

Теперь мы можем использовать отражение, чтобы вызвать требуемый общий метод...

typeof(ClassExample)
    .GetMethod("DoSomething")
    .MakeGenericMethod(p.DisplayType)
    .Invoke(this, new object[] { p.Name, convertedValue });

Ответ 5

Строго говоря, вы можете использовать MethodInfo.MakeGenericMethod.

Но я рекомендую вместо этого заменить DoSomething на не-общую форму, так как не очевидно, действительно ли это должно быть общим.