我有一个实例方法,该方法创建了类的新实例。我希望这是一种类方法。问题在于,我在静态方法中尝试调用getType()时会遇到错误。是否可以将此方法转换为静态方法?
错误
非静态字段,方法或属性'object.getType()'。
需要一个对象引用。
customer.new
public object WithAttributes(ExpandoObject valueObject)
{
var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.GetSetMethod() != null);
var self = Activator.CreateInstance(GetType());
var values = (IDictionary<string, object>)valueObject;
foreach (var property in properties)
{
if (values.Keys.Contains(property.Name))
{
var val = values[property.Name];
property.SetValue(self, values[property.Name]);
}
}
return self;
}
baseentity.cs
public class BaseEntity
{
public Int64 Id { get; set; }
public DateTime AddedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string IPAddress { get; set; }
public object WithAttributes(ExpandoObject valueObject)
{
// Same code as above
}
}
customer.cs
public class Customer : BaseEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string MobileNo { get; set; }
}
所需用法
dynamic attributes = new ExpandoObject();
attributes.FirstName = "James";
attributes.LastName = "Jones";
var customer = Customer.WithAttributes(attributes);
好吧,不幸的是,对于您来说,不可能从基本抽象类型的静态方法中获取实现类型。根据里德·科普西(Reed Copsey)在这里的回答以及乔恩·斯基特(Jon Skeet)的回答。正如您在乔恩(Jon)的答案中看到的那样,C#编译器将静态方法与其声明的类型相关联,即使它是从派生类型执行的。
这意味着您的抽象类必须意识到实现它的类型,或者至少此方法必须意识到它被调用的类型。
做到这一点的一种方法是将WithAttributes
创建为通用方法:
public static T WithAttributes<T>((ExpandoObject valueObject)) where T: BaseEntity, new
{
// Here you can use typeOf(T)
}
这有一些优点(例如,您可以简单地编写var self = new T()
而不是使用Activator.CreateInstance()
,而您无需返回object
而不是实际类型。
但是,您不能强制使用此方法传递正确类型的代码 - 没有什么可以阻止您进行这样的事情:
var customer = Customer.WithAttributes<SomeOtherBaseEntityDerivedClass>(attributes);
Rob Leclerc的回答是使用仿制药解决此问题的另一种尝试,只是将整个抽象类创建为通用类,因此,您将拥有
,而不是public class BaseEntity
public class BaseEntity<TChild>
然后您可以使用typeOf(TChild)
。
这与我的建议具有相同的缺点(您可以轻松地进行public class Customer : BaseEntity<SomeOtherType>
)。
丹尼尔·怀特(Daniel A.
public static object WithAttributes(Type type, ExpandoObject valueObject)
再次,它具有与使用通用方法相同的缺点,但是它也具有您的方法的缺点 - 它必须返回object
,并且您必须使用Activator.CreateInstance
。
得出结论 - 您要要求的是不能安全完成的。
我不建议将这些方法中的任何一种用于公共API,但是如果您知道您的团队是唯一可以继承基础的程序员,那么只要您确保每个人都知道编译器可以,我可能会采用通用方法't保护他们免于使用错误的类型参数。