C# 还有一个问题是如何减少C语言中的代码重复#
我有两个对象,我们称它们为A和B 每个都包含以下属性:C# 还有一个问题是如何减少C语言中的代码重复#,c#,generics,salesforce,refactoring,traits,C#,Generics,Salesforce,Refactoring,Traits,我有两个对象,我们称它们为A和B 每个都包含以下属性: [IgnoreDataMember] public string SalesforceId { get; set; } 然后我有另外两个对象,让我们称它们为UpdatedA和UpdatedB,它们分别扩展了A和B,只包括: [DataMember(Name = "sf__Id")] public new string SalesforceId { get;
[IgnoreDataMember]
public string SalesforceId { get; set; }
然后我有另外两个对象,让我们称它们为UpdatedA和UpdatedB,它们分别扩展了A和B,只包括:
[DataMember(Name = "sf__Id")]
public new string SalesforceId { get; set; }
[DataMember(Name = "sf__Created")]
public bool SalesforceCreated { get; set; }
这样做的原因是,我可以使用ServiceStack
将A和B转换为CSV文件,然后再次使用它将CSV文件从Salesforce转换回C#对象(如果我不忽略SalesforceId
,上传到Salesforce批量API 2.0将失败)
所以,这个问题的第一个问题是,我真的需要为UpdatedA和UpdatedB创建两个单独的类吗,因为这些类几乎相同,实际上都是恶作剧,因为我只在以下两种方法中使用它们:
private Dictionary<string, A> Update(Dictionary<string, A> aByExternalIds, RelayerContext context) {
IConfiguration config = context.Config;
string url = $"{config["SalesforceInstanceBaseUrl"]}/services/data/{config["SalesforceVersion"]}/jobs/ingest/{context.job.Id}/successfulResults";
this.restClient.Get(url, context.token)
.FromCsv<List<UploadedA>>()
.ForEach((updatedA) => {
if (aByExternalIds.TryGetValue(updatedA.ExternalId, out A oldA)) {
oldA.SalesforceId = updatedA.SalesforceId;
}
});
return aByExternalIds;
}
private Dictionary<string, B> Update(Dictionary<string, B> bBySalesforceAId, RelayerContext context) {
IConfiguration config = context.Config;
string url = $"{config["SalesforceInstanceBaseUrl"]}/services/data/{config["SalesforceVersion"]}/jobs/ingest/{context.job.Id}/successfulResults";
this.restClient.Get(url, context.token)
.FromCsv<List<UploadedB>>()
.ForEach((updatedB) => {
if (bBySalesforceAId.TryGetValue(updatedB.A__c, out B oldB)) {
oldB.SalesforceId = updatedB.SalesforceId;
}
});
return bBySalesforceAId;
}
它可以用来返回updatedA.ExternalId
或updatedB.A\u c
但是如果我使用泛型,我不确定方法签名会是什么样子。
另外,如果我不知道如何以通用方式处理fromcvs()
和fromcvs()
(可能传递函数?)
总之,我想做的是将这两种方法简化为一种,如果我能删除一个或两个上传的类,那就更好了
有什么想法吗?像这样的想法怎么样:
public interface IBase
{
string SalesforceId { get; set; }
}
public class A : IBase
{
public string SalesforceId { get; set; }
}
public class UploadedA : A
{
public new string SalesforceId {
get => base.SalesforceId;
set => base.SalesforceId = value; }
public bool SalesforceCreated { get; set; }
}
public static void Update<T, TU>(Dictionary<string, T> oldBySalesForceId, Func<TU, string> updatedId)
where TU : T
where T : IBase
{
// Call service and read csv to produce a list of uploaded objects...
// Substituting with an empty list in the example
var list = new List<TU>();
foreach (var updated in list)
{
if (oldBySalesForceId.TryGetValue(updatedId(updated), out var old))
{
old.SalesforceId = updated.SalesforceId;
}
}
}
公共接口IBase
{
字符串SalesforceId{get;set;}
}
公共A类:IBase
{
公共字符串SalesforceId{get;set;}
}
公共类上载A:A
{
公共新字符串SalesforceId{
get=>base.SalesforceId;
set=>base.SalesforceId=value;}
public bool SalesforceCreated{get;set;}
}
公共静态无效更新(字典oldBySalesForceId,Func updateId)
图:T在哪里
T:IBase在哪里
{
//调用服务并读取csv以生成上载对象的列表。。。
//在示例中用空列表替换
var list=新列表();
foreach(列表中更新的var)
{
if(oldBySalesForceId.TryGetValue(updateId(updated),out var old))
{
old.SalesforceId=updated.SalesforceId;
}
}
}
我删除了一些与示例不相关的细节。这使用带有约束的泛型和接口来确保更新的和旧的值都具有SalesForceId
我更改了派生类,使其使用与基类相同的SalesforceId。如果愿意,您可以将其更改为virtual/override,但基类和派生类都具有相同名称的独立属性可能不是一个好主意,因为这样会造成混淆
它使用委托来描述UpdatedA/UpdatedB的id/key。如果愿意,您可以使用接口。看起来很有希望。我会在周一上班的时候试一试,在我得到更好的答案之前接受它是否有效。:-)我似乎缺少了一个基本要素(对于一个更有经验的C#程序员来说,这可能是显而易见的):我应该如何从我的代码中邀请新方法,包括任何必要的类型参数此.Update(/*参数在此*/)`
public interface IBase
{
string SalesforceId { get; set; }
}
public class A : IBase
{
public string SalesforceId { get; set; }
}
public class UploadedA : A
{
public new string SalesforceId {
get => base.SalesforceId;
set => base.SalesforceId = value; }
public bool SalesforceCreated { get; set; }
}
public static void Update<T, TU>(Dictionary<string, T> oldBySalesForceId, Func<TU, string> updatedId)
where TU : T
where T : IBase
{
// Call service and read csv to produce a list of uploaded objects...
// Substituting with an empty list in the example
var list = new List<TU>();
foreach (var updated in list)
{
if (oldBySalesForceId.TryGetValue(updatedId(updated), out var old))
{
old.SalesforceId = updated.SalesforceId;
}
}
}