C#的类型约束问题

时间:2010-05-27 04:05:39

标签: c# reflection generics constraints

我现在遇到了关于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是Employees,Offices ...的基类, 它可以通过静态方法获取Codes.Get,其中T:CodeObject

但是上面的代码无法编译,因为错误#CS0314

方法ConvertToObject的泛型类型T没有任何约束 但Codes.Get请求T必须是CodeObject的子类

我尝试使用重载来解决问题但不行。

有没有办法解决问题?喜欢反思?

4 个答案:

答案 0 :(得分: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);
}

认为你必须将param转换为ConvertCodeObjectToObject,因为Type约束。

答案 1 :(得分: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的子类。

答案 2 :(得分:0)

您的转化方法必须具有相同的约束才能调用Codes.Get<T>并满足<T>的约束。

试试这个:

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

编辑:有人指出,现在你有了约束,永远不会是int或string。此外,检查以确保它是CodeObject类型是由约束完成的。

这实质上使包装方法“额外”而不需要。只需调用Codes.Get,除非您有充分的理由进行抽象。

希望这有帮助。

答案 3 :(得分:-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 });
    }
}