用ctor中的obj列表初始化类成员是不是一种糟糕的做法


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会让我有点困扰,除非它管理得很好,因此一切都会好起来。。。可以使用默认值,但这是基类的角色,而不是子类,除非必须更改它。

相关内容

最新更新