Типовая проблема контрацепции C # - PullRequest
0 голосов
/ 27 мая 2010

Теперь я сталкиваюсь с проблемой ограничения типа c #.

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

static string ConvertToString(Type type, object val) {
 if (type == typeof(string)) return (string)val;
 if (type == typeof(int)) return val.ToString();
 if (type.IsSubclassOf(typeof(CodeObject))) return ((CodeObject)val).Code;
}

static T ConvertToObject<T>(string val) {
 Type type = typeof(T);
 if (type == typeof(string)) return (T)(object)val;
 if (type == typeof(int)) return (T)(object)int.Parse(val);
 if (type.IsSubclassOf(typeof(CodeObject))) return Codes.Get<T>(val);
}

где CodeObject является базовым классом сотрудников, офисов ..., которые могут быть получены статическим методом Codes.Get где T: CodeObject

, но код выше не может быть скомпилирован, потому что ошибка # CS0314

универсальный тип T метода ConvertToObject не имеет никаких ограничений но запрос Codes.Get T должен быть подклассом CodeObject

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

есть ли способ решить проблему? как отражение?

Ответы [ 4 ]

2 голосов
/ 27 мая 2010

Я думаю, что ваша подпись функции нуждается в ограничении типа; но так как все перестановки не нуждаются в этом ограничении, я бы сделал вспомогательную функцию; что-то вроде:

static T ConvertToObject<T>(string str) {
 Type type = typeof(T);
 if (type == typeof(string)) return (T)(object)val;
 if (type == typeof(int)) return (T)(object)int.Parse(val);
 if (type.InSubclassOf(typeof(CodeObject))) return ConvertCodeObjectToObject((CodeObject)val);
}

static T ConvertCodeObjectToObject<T>(string str) where T: CodeObject {
 return Codes.Get<T>(val);
}

Я думаю , что вам нужно преобразовать параметр в ConvertCodeObjectToObject из-за ограничения типа.

0 голосов
/ 27 мая 2010

Я попытался решить проблему с помощью отражения.

if (type.IsSubclassOf(typeof(CodeObject))) {
    var baseMethod = typeof(Codes).GetMethod("Fetch<>", BindingFlags.Static | BidingFlags.Public, null, new Type[] {typeof(string)}, null);
    if (baseMethod != null) {
        var genericMethod = baseMethod.MakeGenericMethod(type);
        if (genericMethod != null)
            return (T)genericMethod.Invoke(null, new string[] { val });
    }
}
0 голосов
/ 27 мая 2010

Ваш метод преобразования должен иметь идентичные ограничения, чтобы иметь возможность вызывать Codes.Get<T> и удовлетворять ограничениям для <T>.

Попробуйте это:

static T ConvertToObject<T>(string str) where T:CodeObject
{
   return Codes.Get<T>(str);
}

Edit: Как кто-то указал, теперь, когда у вас есть ограничение, никогда не будет int или string. Кроме того, ограничение, чтобы убедиться, что оно имеет тип CodeObject, выполняется ограничением.

Это делает метод обёртывания «лишним» и не нужен. Просто позвоните Codes.Get, если у вас нет веских причин для его абстрагирования.

Надеюсь, это поможет.

0 голосов
/ 27 мая 2010

Вы хотите добавить ограничение типа, например так:

static T ConvertToObject<T>(string str) where T : CodeObject
{
    Type type = typeof(T);
    if (type == typeof(string)) return (T)(object)val;
    if (type == typeof(int)) return (T)(object)int.Parse(val);
    if (type.InSubclassOf(typeof(CodeObject))) return Codes.Get<T>(val);
}

Ограничение типа - это бит "where T". Вы в основном говорите компилятору, что T должен быть подклассом CodeObject.

...