如何使用 C# 泛型进行泛化?
How to generalize using C# generics?
我正在尝试制作一个结构,可以将各种文件格式解析为实体类型对象,以便存储在数据库中。
我想让代码尽可能易于阅读,并使用彼此独立的其他文件格式和实体类型进行扩展。
一般来说,我有一个文件解析器,它使用一个文件和 returns一个 DTO 模型。然后这个 DTO 模型被一个转换器使用,returns 一个数据库实体对象。解析器、转换器和 DTO 模型都扩展了抽象 classes 以避免代码重复。该过程由名为 Service 的 class 执行。
代码的本质如下:
class Service
{
public void Run()
{
var model = new DerivedModel<DerivedRow>();
var parser = new DerivedParser<DerivedModel<DerivedRow>>(model);
}
}
class DerivedModel<TRow> : AbstractModel<DerivedRow>
where TRow : DerivedRow
{
public override DerivedRow NewRow()
{
return new DerivedRow();
}
}
abstract class AbstractModel<TRow>
{
public abstract TRow NewRow();
}
class DerivedRow : AbstractRow
{
}
abstract class AbstractRow
{
}
class DerivedParser<TModel> : AbstractParser<TModel>
where TModel : AbstractModel<AbstractRow>
{
public DerivedParser(TModel model)
{
Model = model;
}
public override TModel Parse()
{
var row = Model.NewRow();
return Model;
}
}
abstract class AbstractParser<TModel>
{
public TModel Model { get; protected set; }
public abstract TModel Parse();
}
类型检查器抱怨服务中的这一行代码class:
var parser = new DerivedParser<DerivedModel<DerivedRow>>(model);
错误是:
Error CS0311 The type 'Sandbox.GenericTest.DerivedModel<Sandbox.GenericTest.DerivedRow>' cannot be used as type parameter 'TModel' in the generic type or method 'DerivedParser<TModel>'. There is no implicit reference conversion from 'Sandbox.GenericTest.DerivedModel<Sandbox.GenericTest.DerivedRow>' to 'Sandbox.GenericTest.AbstractModel<Sandbox.GenericTest.AbstractRow>'.
我试过将一些接口与抽象 classes 结合使用,但这只会使事情变得复杂。
有什么建议吗?我尝试用这种方式在 C# 中做的事情是否可行?
尝试传递 TModel 并且错误消失。
您需要向 AbstractParser 提及模型的类型。一旦通过,该错误就会消失。
这是代码
class Service
{
public void Run()
{
var model = new DerivedModel<DerivedRow>();
var parser = new DerivedParser<DerivedModel<DerivedRow>, DerivedRow>(model);
}
}
class DerivedModel<TRow> : AbstractModel<DerivedRow>
where TRow : DerivedRow
{
public override DerivedRow NewRow()
{
return new DerivedRow();
}
}
abstract class AbstractModel<TRow> where TRow : AbstractRow
{
public abstract TRow NewRow();
}
class DerivedRow : AbstractRow
{
}
abstract class AbstractRow
{
}
class DerivedParser<TModel, TRow> : AbstractParser<TModel, TRow>
where TModel : AbstractModel<TRow> where TRow : AbstractRow
{
public DerivedParser(TModel model)
{
Model = model;
}
public override TModel Parse()
{
var row = Model.NewRow();
return Model;
}
}
abstract class AbstractParser<TModel, TRow> where TRow : AbstractRow
{
public TModel Model { get; protected set; }
public abstract TModel Parse();
}
我正在尝试制作一个结构,可以将各种文件格式解析为实体类型对象,以便存储在数据库中。
我想让代码尽可能易于阅读,并使用彼此独立的其他文件格式和实体类型进行扩展。
一般来说,我有一个文件解析器,它使用一个文件和 returns一个 DTO 模型。然后这个 DTO 模型被一个转换器使用,returns 一个数据库实体对象。解析器、转换器和 DTO 模型都扩展了抽象 classes 以避免代码重复。该过程由名为 Service 的 class 执行。
代码的本质如下:
class Service
{
public void Run()
{
var model = new DerivedModel<DerivedRow>();
var parser = new DerivedParser<DerivedModel<DerivedRow>>(model);
}
}
class DerivedModel<TRow> : AbstractModel<DerivedRow>
where TRow : DerivedRow
{
public override DerivedRow NewRow()
{
return new DerivedRow();
}
}
abstract class AbstractModel<TRow>
{
public abstract TRow NewRow();
}
class DerivedRow : AbstractRow
{
}
abstract class AbstractRow
{
}
class DerivedParser<TModel> : AbstractParser<TModel>
where TModel : AbstractModel<AbstractRow>
{
public DerivedParser(TModel model)
{
Model = model;
}
public override TModel Parse()
{
var row = Model.NewRow();
return Model;
}
}
abstract class AbstractParser<TModel>
{
public TModel Model { get; protected set; }
public abstract TModel Parse();
}
类型检查器抱怨服务中的这一行代码class:
var parser = new DerivedParser<DerivedModel<DerivedRow>>(model);
错误是:
Error CS0311 The type 'Sandbox.GenericTest.DerivedModel<Sandbox.GenericTest.DerivedRow>' cannot be used as type parameter 'TModel' in the generic type or method 'DerivedParser<TModel>'. There is no implicit reference conversion from 'Sandbox.GenericTest.DerivedModel<Sandbox.GenericTest.DerivedRow>' to 'Sandbox.GenericTest.AbstractModel<Sandbox.GenericTest.AbstractRow>'.
我试过将一些接口与抽象 classes 结合使用,但这只会使事情变得复杂。
有什么建议吗?我尝试用这种方式在 C# 中做的事情是否可行?
尝试传递 TModel 并且错误消失。 您需要向 AbstractParser 提及模型的类型。一旦通过,该错误就会消失。 这是代码
class Service
{
public void Run()
{
var model = new DerivedModel<DerivedRow>();
var parser = new DerivedParser<DerivedModel<DerivedRow>, DerivedRow>(model);
}
}
class DerivedModel<TRow> : AbstractModel<DerivedRow>
where TRow : DerivedRow
{
public override DerivedRow NewRow()
{
return new DerivedRow();
}
}
abstract class AbstractModel<TRow> where TRow : AbstractRow
{
public abstract TRow NewRow();
}
class DerivedRow : AbstractRow
{
}
abstract class AbstractRow
{
}
class DerivedParser<TModel, TRow> : AbstractParser<TModel, TRow>
where TModel : AbstractModel<TRow> where TRow : AbstractRow
{
public DerivedParser(TModel model)
{
Model = model;
}
public override TModel Parse()
{
var row = Model.NewRow();
return Model;
}
}
abstract class AbstractParser<TModel, TRow> where TRow : AbstractRow
{
public TModel Model { get; protected set; }
public abstract TModel Parse();
}