gpt4 book ai didi

c# - 使用设计模式向 C# 中的类添加功能

转载 作者:太空宇宙 更新时间:2023-11-03 21:06:56 25 4
gpt4 key购买 nike

我的挑战:将从 XML 序列化和反序列化到 XML 的能力添加到一个只知道如何使用 JSON 执行此操作的类。

虽然我熟悉设计模式的“基本”应用,但我是 C# 的新手。

一位同事提出了以下建议:

我的建议是你注入(inject)一个序列化器(编写一个 IRDCSerizliazer 接口(interface),它是一个装饰器/适配器,包装它构造的任何序列化器)。

他们在这里非常重视“开放/封闭”原则,这可能就是为什么建议使用接口(interface)和模式,而不是向类中添加任何代码。

我刚刚在 C# 中构建了一个示例“装饰器”模式,以确保我了解如何执行“标准”装饰器模式对于这种情况感觉很复杂......(尽管我很高兴得到纠正)

我想我需要一些抽象“Serializer”并允许“Serializer.serialize() 和 Serializer.deserialize()”的东西从我目前只知道 JSON 的工作类调用。我还认为我希望能够根据它的构造方式在“Serializer”中拥有 JSON 代码或 XML 代码。 IE。我从我同事的提示中假设他构建了这样的模式...

正如他们所说,我能感觉到这“就在我的舌尖上”,但我很难迈出这一步。 “纯”装饰器模式似乎太复杂了。帮助将不胜感激。

请不要因为我应该如何在办公室寻求更多帮助而生气 - 显然我不想那样做,否则我不会在这里寻求帮助。

我的工作类在下面 - 你会看到目前它只是直接调用 JSON 序列化和反序列化......显然这必须改变。不要太担心它的作用 - 它是棘手的反射东西 - 关键是可以使用“注入(inject)接口(interface)”的概念在此类中使用 XML 和 JSON 进行序列化和反序列化。

namespace XXXXXXXXXXXX
{
public interface IRecordSearchClientAdapter
{
string CallCorrectMethod(ClientServiceTypes component, string method, string request, Type[] paramTypes);
}

public class RecordSearchClientAdapter : IRecordSearchClientAdapter
{
private IDictionary<ClientServiceTypes, object> componentMappings;

public static IRecordSearchClientAdapter Create(IDictionary<ClientServiceTypes, object> clients)
{
return new RecordSearchClientAdapter(clients);
}

private RecordSearchClientAdapter(IDictionary<ClientServiceTypes, object> clients)
{
componentMappings = clients;
}
public string CallCorrectMethod(ClientServiceTypes component, string method, string request, Type[] paramTypes)
{
dynamic parsedrequest = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(request);
//use another method to decide if it's JSON or XML, don't worry about injecting a Decorator:Interface?
//dynamic parsedrequest = DeserializeObject(request);
return CallCorrectMethod(component, method, parsedrequest, paramTypes);
}

//In this method, check for XML or JSON - then forward to the appropriate method.
private string DeserializeObject(string request)
{
//stub - fixme!
return null;
}

private string CallCorrectMethod(ClientServiceTypes component, string method, JObject request, Type[] paramTypes)
{
object client = componentMappings[component];

MethodInfo mi = FindExactMethod(client, method, request, paramTypes);

string response = null;

if (paramTypes.Length == 1) // just one "request" object
{
var obj = DeserializeGenericObject(request, paramTypes[0]);
var methodResponse = mi.Invoke(client, new object[] { obj });
response = Newtonsoft.Json.JsonConvert.SerializeObject(methodResponse);
}
else // multiple parameters, need to grab them from the request
{
JEnumerable<JToken> tokens = request.Children();
IEnumerator<JToken> tokenEnumerator = tokens.GetEnumerator();
List<object> args = new List<object>();
foreach (Type t in paramTypes)
{
if (!tokenEnumerator.MoveNext())
{
throw new ArgumentException("Number of arguments in request doesn't match number of arguments in method");
}

args.Add(DeserializeGenericObject(tokenEnumerator.Current.First, t));
}
var methodResponse = mi.Invoke(client, args.ToArray());
response = Newtonsoft.Json.JsonConvert.SerializeObject(methodResponse);
}

return response;
}

private MethodInfo FindExactMethod(object client, string method, JObject request, Type[] paramTypes)
{
// get the method that matches the name and type params
MethodInfo mi = client.GetType().GetMethod(method, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance, null, paramTypes, null);
return mi;
}

private object DeserializeGenericObject(JToken token, Type objectType)
{
Type myClassType = this.GetType();
MethodInfo methodToCall = myClassType.GetMethod("DeserializeGenericTemplate", BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo genericMethodToCall = methodToCall.MakeGenericMethod(new Type[] { objectType });
object newObject = genericMethodToCall.Invoke(this, new[] { token });

return newObject;
}

private T DeserializeGenericTemplate<T>(JToken token)
{
T obj = token.ToObject<T>();
return obj;
}
}

最佳答案

不确定为什么在一个类中需要这个。您的设计似乎有点矫枉过正。我会有一个接口(interface)来定义常见的行为(序列化和反序列化)和两个实现类,一个用于 JSON,另一个用于 XML,就像这样

public interface ISerialize<T>
{
T Deserialize<T>(string input);
string Serialize(T type)
}

public class JsonSerializer<T> : ISerialize<T>
{
T Deserialize<T>(string input) {...}
string Serialize(T type) {...}
}

public class XmlSerializer<T> : ISerialize<T>
{
T Deserialize<T>(string input) {...}
string Serialize(T type) {...}
}

下面是我将如何使用它

public class Foo<T>
{
private ISerializer<T> _serialiser;

public Foo<T>(ISerializer<T> serialiser)
{
_serialiser = serialiser;
}

void DoFoo()
{
string result = serialiser.Serialize(instanceOfA_1);
var instanceOfA_2 = serialiser.Deserialize<ClassA>(result);
}
}

如果您不知道需要哪个序列化程序 - 使用接口(interface),例如,通过将其注入(inject)构造函数。

关于c# - 使用设计模式向 C# 中的类添加功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40686736/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com