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