【发布时间】:2017-01-28 16:10:43
【问题描述】:
我想知道如何通过传递泛型类型从基类中访问扩展方法。
我有几个不同的类,它们都包含 ToModel 和 ToContract Funcs。 这些方法是从实体框架类型切换到数据契约,反之亦然。
他们都做同样的重复调用,所以我想浓缩一下代码。
我尝试过使用反射调用函数。和许多其他方法都无济于事。我在下面的代码中简化了我面临的问题。
我的问题是我无法从基类中访问扩展方法。请帮忙。
我收到错误:类不包含“ToModel”方法的定义。
简化代码
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestExtensions
{
public class Program : Base<Client>
{
static void Main(string[] args)
{
Client c = new Client();
c.FirstName = "First Name";
Console.WriteLine(c.FirstName);
c.ToModel();
Console.WriteLine(c.FirstName);
Program p = new Program();
p.go(c);
}
public void go(Client c)
{
base.ChangeNameAgain(c);
Console.WriteLine(c.FirstName);
}
}
}
扩展类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestExtensions
{
public static class ExtensionClass
{
public static Client ToModel(this Client c)
{
c.FirstName = "First Name Changed";
return c;
}
}
}
客户端类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestExtensions
{
public class Client
{
public string FirstName { get; set; }
}
}
基类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestExtensions
{
public class Base<T>
{
public T ChangeNameAgain(T c)
{
// This is where I need help
// Need to invoke the ToModel Method using reflection
return (T) c;
}
}
}
我的实际代码
基础
public class BaseApi<TContractType, TModelType> : ApiController
where TModelType : DataModelBase, IApiExtensionModel, new()
where TContractType: DataContractBase, IApiExtensionContract, new()
{
public TContractType Create(
IGenericRepository<TModelType> repo,
TContractType obj)
{ I
// This is what is giving me trouble
var instance = (TContractType)
Activator.CreateInstance(typeof(TContractType),
new object[] { obj });
var modelMap = instance.ToModel();
var ret = (dynamic)repo.Edit(modelMap);
return ret.ToContract();
}
}
实际有效的代码
尽量使其通用,因为它是重复的。
[Microsoft.AspNetCore.Mvc.HttpPost]
public patientContract.Patient CreatePatient(
[Microsoft.AspNetCore.Mvc.FromBody] patientContract.Patient patient)
{
var map = patient.ToModel();
var ret = _patientRepo.Add(map);
return ret.ToContract();
}
扩展
public static class PatientContractExtension
{
public static Model.Patient ToModel(this Contract.Patient patientContract)
{
var map = Mapper.Map<Contract.Patient, Model.Patient>(patientContract);
return map;
}
public static Contract.Patient ToContract(this Model.Patient patientModel)
{
var map = Mapper.Map<Model.Patient, Contract.Patient>(patientModel);
return map;
}
}
【问题讨论】:
-
为什么你使用
dynamic c而不是T c作为参数? -
ToModel在Client上运行,因此您需要将c声明为Client或带有约束TClient的通用TClient。 -
@Theodoros 我不知道 TClient 会是这样,所以我不能将它指定为客户端类型
-
整个架构让我想尖叫着逃跑。我从未见过有人试图以这种方式将
Program与另一种类型的行为结合起来。你正在建造一座纸牌屋。请重新审视“封装”和“单一责任”原则。
标签: c# generics dynamic extension-methods base-class