我有以下抽象类:
public abstract partial class AsyncResult
{
}
以及从它继承的其他7个类(这里只有2个供参考):
public partial class AsyncSearchResult : AsyncResult
{
private SearchResult searchResultField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace="urn:core_2020_2.platform.webservices.netsuite.com", Order=0)]
public SearchResult searchResult
{
get
{
return this.searchResultField;
}
set
{
this.searchResultField = value;
}
}
}
public partial class AsyncGetListResult : AsyncResult
{
private ReadResponseList readResponseListField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public ReadResponseList readResponseList
{
get
{
return this.readResponseListField;
}
set
{
this.readResponseListField = value;
}
}
}
我有一个返回抽象类型的方法,为了访问所需的属性,我需要将它转换为特定类型之一。
我无法在编译时找到一种方法来转换它,而不为每种情况编写7个it,并且经常重复代码。
感谢任何帮助。
发布于 2021-07-01 12:43:20
为此,我喜欢使用访问者模式:
public interface IAsyncResultVisitor
{
void Accept(AsyncSearchResult searchResult);
void Accept(AsyncGetListResult getListResult);
// Etc...
}
public abstract partial class AsyncResult
{
public abstract void Visit(IAsyncResultVisitor visitor);
}
public partial class AsyncSearchResult : AsyncResult
{
// ...
public override void Visit(IAsyncResultVisitor visitor) => visitor.Accept(this);
}
然后:
public class AsyncResultProcessor : IAsyncResultVisitor
{
public void ProcessAsyncResult(AsyncResult asyncResult)
{
asyncResult.Visit(this);
}
public void Accept(AsyncSearchResult searchResult)
{
// Access strongly-typed members of searchResult
}
public void Accept(AsyncGetListResult getListResult)
{
// Access strongly-typed members of getListResult
}
}
请注意,switch语句和switch表达式在这里也有帮助,尽管它们不能确保您已经涵盖了每一种情况(就像访问者模式所做的那样):
switch (asyncResult)
{
case AsyncSearchResult searchResult:
// ...
break;
}
发布于 2021-07-01 14:30:55
我会用不同的方式实现访客。@canton7 7实现的问题是,数据必须知道人们应该如何使用它,但它只是普通的数据!
首先:AsyncResult
应该有private protected
构造函数,所以其他程序集都不能“实现”这个抽象类。
public abstract class AsyncResult
{
private protected AsyncResult() {}
}
public sealed class ResultOne : AsyncResult()
{
public string Data { get; set; }
}
// 6 more to go
使接口匹配所有类型
public interface IAsyncResultVisitor
{
void Visit(AsyncResult result);
void VisitResultOne(ResultOne result);
void VisitResultTwo(ResultTwo result);
// 5 more to go
}
并创建默认访问者,它将对每种包含访问策略的类型具有属性
public sealed class LambdaAsyncResultVisitor : IAsyncResultVisitor
{
public Action<ResultOne> OnVisitOne { get; set; }
public void VisitResultOne(ResultOne result)
{
if (OnVisitOne is null)
throw new InvalidOperationException("...");
OnVisitOne.Invoke(result);
}
// 6 more to go
}
这样我们就可以这样使用它了。
AsyncResult result = ...;
string someString = "";
new LambdaAsyncResultVisitor
{
OnVisitOne = r => someString = r.Data,
OnVisitTwo = r => someString = "two",
OnVisitThree => _ => throw new Exception("I know that is is impossible"),
}.Visit(result);
HandleSomeString(someString);
这比默认的访问者模式提供了更多的灵活性。
https://stackoverflow.com/questions/68210359
复制相似问题