2010-05-27 2 views
0

Я встречаю проблему с типом contraint C# now.Проблема с отображением типа C#

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

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

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

я пытался использовать перегрузку, чтобы решить эту проблему, но п ot ok.

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

+0

просьба уточнить, ConvertToObject (строка строка) должна быть ConvertToObject (строка Вал), как ул не упоминается в теле метода, но Допустимы. – Handcraftsman

+3

1. 'InSubclassOf' ->' IsSubclassOf' 2. 'val' ->' str' 3. Отсутствие операторов возврата для обоих методов. Лучше всего отправлять код, который компилируется, он помогает получить правильный ответ. – Kobi

+2

Учитывая ответы с ограничением типа, проверки типов в ConvertToObject теперь излишни, поскольку общее ограничение не позволяет пользователю вызывать 'ConvertToObject ' в первую очередь. Проверка типа для 'type.InSubclassOf (typeof (CodeObject)' является излишней, так как условие гарантии всегда выполняется. Весь метод можно свести к 'T ConvertToObject (строка str) {return Codes.Get (str); } 'или просто бесполезная оболочка вокруг другого метода. Другими словами, вам не нужен какой-либо метод, который вы пытаетесь написать. – Juliet

ответ

-1

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

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

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

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.

+0

Кажется хорошим, но тогда он не может вернуть 'int' или' object'. Метод литья, вероятно, правильный ответ здесь. – Kobi

+0

Если T ограничено CodeObject, то T не может быть int или string. –

+0

О да, я пропустил эту часть. Я думаю, что ответ Джона Уэлдона является лучшим в этом случае. –

0

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

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

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

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

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

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

2

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

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

Если вы выполняете бросок, тип для T всегда будет CodeObject. В зависимости от реализации Codes.Get это может иметь существенное значение. –

+0

Должен быть ясным ... всегда будет иметь тип CodeObject и никогда не будет его подклассами. –

+0

Спасибо! однако, поскольку метод, определенный как ConvertCodeObjectToObject (строка), , мне нужно вернуть ConvertCodeObjectToObject '' '' '' '' ((CodeObject) val). и возникла проблема с тем же # CS0314. – but

Смежные вопросы