“ where this:class”的错误语法

时间:2018-12-04 17:08:52

标签: c# generics reflection casting extension-methods

y

TryCast可以用作:

  

someString.TryCast ()

但它不仅限于类,因为“ where this:class”返回语法错误”,这意味着,没有“ this:class”约束,它将出现在int,char等变量上。< / p>

我正在寻找一种将“此对象父对象”类型限制为仅类变量的方法,因为在我的用例中,在诸如int和char这样的简单类型上使用它是没有意义的。

注意:

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

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;
    }
}

然后像这样使用它:

  

someString.TryCastWorse <字符串,someClassToCastTo>()

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

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

2 个答案:

答案 0 :(得分:1)

答案是肯定的。除非参数具有class约束,否则不能将其约束为不是值类型。

因此,您要么只能指定通用参数,要么可以允许值类型和代码大量检查。

答案 1 :(得分:1)

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

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

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>();