将实例方法转换为类方法C#



我有一个实例方法,该方法创建了类的新实例。我希望这是一种类方法。问题在于,我在静态方法中尝试调用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保护他们免于使用错误的类型参数。

最新更新