Общий метод Выполняется со временем выполнения
У меня есть следующий код:
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()
есть ли другой способ использовать эту функцию?
Ответы
Ответ 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 на не-общую форму, так как не очевидно, действительно ли это должно быть общим.