“where this : class”语法错误

“where this : class” wrong syntax

public static class Extensions
{
    public static T TryCast<T>(this object parent)
        where T : class
        where this : class
    {
        T child = (T)Activator.CreateInstance(typeof(T));
        foreach (PropertyInfo prop in parent.GetType().GetProperties())
        {
            child.GetType().GetProperty(prop.Name)?.SetValue(child, prop.GetValue(parent));
        }

        return child;
    }
}

TryCast 可用作:

someString.TryCast< someClassToCastTo >()

但它不仅限于classes,因为"where this : class" returns语法错误”,这意味着,如果没有"this : class"限制,它将出现关于 int、char 等变量

我正在寻找一种方法来将类型 "this object parent" 限制为仅 class 变量,因为在我的用例中,将它用于 int 和 char 等简单类型是没有意义的。

注:

可以像这样捕获和限制父类的类型:

public static T2 TryCastWorse<T, T2>(this T parent)
    where T : class
    where T2 : class
{
    T2 child = (T2)Activator.CreateInstance(typeof(T2));
    foreach (PropertyInfo prop in parent.GetType().GetProperties())
    {
        child.GetType().GetProperty(prop.Name)?.SetValue(child, prop.GetValue(parent));
    }

    return child;
}

然后像这样使用它:

someString.TryCastWorse< string, someClassToCastTo >()

这不是最优的,因为必须指定调用变量的 class,正如 <> 中的第一种类型所观察到的那样,它是一个字符串,它应该始终等于 someString。

在这种情况下,这不是预期的功能,因为它可能会在某些用例中引入错误。

答案是否定的。您不能将参数限制为不是值类型,除非它是具有 class 约束的泛型类型参数。

因此,您要么坚持指定通用参数,要么忍受允许值类型和广泛的代码审查。

您似乎想要一个更清晰的语法来为样板 classes 调用反射构造函数。不幸的是,如果您想要泛型类型验证,则需要将它们与 <T> 语法一起传递给方法。

另一种方法可能是让所有样板 classes 扩展一个具有 ConvertTo<T>() 方法的抽象 class:

public abstract class ABoilerplate {
    public T ConvertTo<T>() where T : class {
        T child = (T)Activator.CreateInstance(typeof(T));
        foreach (System.Reflection.FieldInfo fi in typeof(T).GetFields().Where(field => !field.IsStatic))//should do validations
            fi.SetValue(
                child,
                this.GetType().GetField(fi.Name).GetValue(this));
        return child;
    }
}
public class SimpleClass : ABoilerplate {
    public int ID;
}
public class DuplicateSimpleClass {
    public int ID;
}

然后点赞

SimpleClass instance1 = new SimpleClass() { ID = 1 };
DuplicateSimpleClass instance2 = instance1.ConvertTo<DuplicateSimpleClass>();