我有这段代码以通用的方式创建新对象:
var user = User.Create<User>(c => c.Name = "321X");
我不喜欢的是我需要传递'通用符号'&lt; T&gt;为每个创建调用。毕竟我创建了一个我已经提到的对象......
此当前功能背后的代码是:
public class User : CreateBase
{
public string Name { get; set; }
}
public abstract class CreateBase
{
public DateTime CreateDate { get; set; }
public Guid Guid { get; set; }
public static T Create<T>(Action<T> init) where T : CreateBase, new()
{
T obj = new T();
obj.Guid = Guid.NewGuid();
obj.DateTime = DateTime.Now;
init(obj);
return obj;
}
}
是否可以(以及如何)重构我的代码,以创建对象?
var user = User.Create(c => c.Name = "321X");
谢谢!
答案 0 :(得分:2)
在类级别定义泛型参数:
public abstract class CreateBase<T> where T : CreateBase<T> , new()
{
public static T Create(Action<T> init)
{
//...
}
}
public class User : CreateBase<User>
{
public string Name { get; set; }
}
然后你可以写var user = User.Create(c => c.Name = "321X");
否则编译器无法在不指定类型参数的情况下推断Create
方法的类型。
答案 1 :(得分:2)
你不是很远。试试这个修改:
public abstract class CreateBase<T> where T : CreateBase<T> , new()
{
public DateTime CreateDate { get; set; }
public Guid Guid { get; set; }
public static T Create(Action<T> init)
{
T obj = new T();
obj.Guid = Guid.NewGuid();
obj.CreateDate = DateTime.Now;
init(obj);
return obj;
}
}
public class User : CreateBase<User>
{
public string Name { get; set; }
}
编辑:在之后更新了代码我在本地环境中测试了它。它现在有效。
答案 2 :(得分:1)
更好的方法是将此功能包含在基类的构造函数中(我称之为ModelBase)
public abstract class ModelBase
{
public DateTime CreateDate { get; private set; }
public Guid Guid { get; private set; }
public ModelBase()
{
Guid = Guid.NewGuid();
DateTime = DateTime.Now;
}
}
public User : ModelBase
{
public User()
: base()
{
}
public User(string name)
: base()
{
Name = name
}
public string Name { get; set; }
}
以标准方式创建用户将自动初始化Guid和日期
var user = new User { Name = "xy };
修改
我添加了第二个带有name参数的构造函数。我想强制初始化名称,删除第一个无参数构造函数。
var user = new User("xy");
答案 3 :(得分:1)
你这样做是错误的。而不是摆脱泛型论点,摆脱(不必要)说User.
。代替:
CreateBase.Create<User>(...)
不再有裁员。
除此之外,通过派生类调用基类的静态成员是一种反模式。
答案 4 :(得分:0)
如果你真的对这个sintax感到不舒服(老实说,我不会在这里看到太多问题)
您可以执行以下操作:
public class User : CreateBase
{
public string Name { get; set; }
public static User Create(Action<User> a)
{
return Create<User>(a); //CALL BASE CLASS GENERIC FUNCTION
}
}
在您可以按照您希望的方式调用它之后:
var user = User.Create(c => c.Name = "321X");