На самом деле вы получаете ошибки компиляции, если передаваемый аргумент не является ссылочным типом. Однако, если вы укажете тип значения, вы можете обойти это, но тогда это допустимый ссылочный тип.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication29
{
class Program
{
static void Main(string[] args)
{
int i = 0;
object o = (object)i;
MyMethod(o);
MyMethod(i); // Doesn't compile.
}
static void MyMethod<T>(T arg) where T : class
{
}
}
}
Если вы получаете эту ошибку, потому что вы что-то делаете во время выполнения, например, используете отражение для вызова метода или вы указываете типы значений, тогда вам просто нужно проверить параметр перед его использованием:
static void MyMethod<T>(T arg) where T : class
{
if (arg is ValueType)
throw new ArgumentException();
}
Обратите внимание, что это перехватит все типы значений, независимо от того, упакованы они или нет. Также обратите внимание, что использование is
также соответствует true для типа в его иерархии (базовые / производные классы), тогда как проверка GetType
против typeof
принимает только тип на этом уровне:
int i = 0;
bool b = i is object;
b = i.GetType() == typeof(object);
Очевидно, что в вашем случае вы не захотите бросить ArgumentException
и, возможно, просто ничего не делать.