ClassName(List<object> obj) : base(obj[0])
{
member1 = obj[1];
...
}
我有一个关于oop C#的作业。我实现了一个工厂设计模式,我正在初始化的类是在运行时确定的。此外,obj列表由于用户输入而发生变化。以这种方式初始化类成员比在ctor中获取所有特定参数的经典方式更糟糕还是最好的做法,比如:
ClassName(int a, float b, ClassName2 c)
我认为您的意思是用List<object>
作为单个参数来实现构造函数,而不是每个属性的多个参数。
由于c#是类型安全的,因此不建议这样做。从各种类型转换到object
并再次转换不仅是危险的,而且速度也很慢,可能会引入难以发现的细微错误。
推荐的方式
public abstract class BaseClass
{
protected BaseClass(string baseName)
{
this.BaseName=baseName;
}
public string BaseName { get; }
}
public class DerivedClass : BaseClass
{
public DerivedClass(string baseName, int iD)
: base(baseName)
{
this.ID=iD;
}
public int ID { get; }
}
不太推荐的方式
使用params object[]
public DerivedClass(params object[] args)
: base( args[0] as string)
{
this.ID = (int)args[1];
}
使用List<object>
public DerivedClass(List<object> args)
: base( args[0] as string)
{
this.ID = (int)args[1];
}
替代型安全方式
您也可以使用ValueTuple
来携带参数
public DerivedClass((string baseName, int id) args)
: base( args.baseName)
{
this.ID = args.id;
}
对于提供的代码:是。
我更想说的是,这既不是一种糟糕的做法,也不是一种观点:这是一个错误。
因为如果列表为空或为null,则会得到一个异常。
您必须在构造函数中检查边界,并以不同的方式执行操作。
例如:
class BaseClass
{
protected void Initialize(object instance)
{
...
}
public BaseClass(object instance)
{
Initialize(instance);
}
}
class ChildClass : BaseClass
{
ChildClass(List<object> items)
{
if ( items.Count > 0 ) Initialize(items[0]);
if ( items.Count > 1 ) member1 = items[1];
...
}
}
也许您可以在此映射表上使用属性的集合(数组、列表…(和循环。
当然,你也可以写这样一个东西:
ChildClass(List<object> items) : base(items != null && items.Count > 0 ? items[0] : null)
但原则上,在不了解更多代码和规范的情况下,null
会让我有点困扰,除非它管理得很好,因此一切都会好起来。。。可以使用默认值,但这是基类的角色,而不是子类,除非必须更改它。