我打赌这是一个非常基本的设计问题,但由于我很难说出来,我找不到任何在线资源来帮我回答。我使用C#6
虽然这是一个设计问题,但我也接受使用c#6独特功能的任何答案。
我的问题:说你有一个简单的课程MyClass
,其属性为MyProp
。 MyClass
也有方法:
public void InitializeMyProp(someValue)
{
MyProp = //use the value of someValue to calculate MyProp
}
此外,MyClass
有许多使用MyProp的公共方法,例如:
public int DependedMethod1()
{
//use the value of MyProp to do some calculations. this method might also fail to initialize MyProp and I'm not sure how to handle this situation
return valueThatDependOnMyProp1;
}
在MyProp
实例化时,MyClass
的值未知。但是,方法DependedMethod1, DependedMethod2, ... , DependedMethodN
都取决于MyProp
的价值。
我的问题:如何在使用之前确保MyProp
已初始化?
我有一些想法,所有这些都是我不喜欢的:
1.当然,我可以为每个方法添加相同的代码DependedMethod
:
if(MyProp == null) throw exception()
但这有三个缺点:a。重复的代码?湾每次调用方法时,异常都需要处理。
DependedMethods
放在内部(静态?)类InnerDependedClass
中,为MyClass
分配InnerDependedClass
类型的字段(让它命名为MyField
)和在InitializeMyProp
实例化。这是一个合理的解决方案,因为如果InitializeMyProp
失败,我就不会实例化MyField
。但问题很严重 - 如果其他类想要使用MyField
的方法,它必须先检查它是否为空 - 这有点像询问MyProp
是否为空。
我仍然在努力在这里完全解释自己。
我的具体问题是:给定二进制文件路径,打开文件,读取其中的前2个字节(偏移键的种类),并保存此键。将文件保存在内存中(我使用InMemoryFileStream)因为源可能会被删除或更改。稍后,当被问到时,使用密钥(再次,偏移)从fileStream中提取特定信息。 问题是,如果文件已损坏/无法打开以进行读取(出于任何原因),则该键将为null。
我相信我这里有一个很大的设计问题。我的代码是下面的
public class MyReaderStream : IDisposable, IMyReaderStream
{
public MemoryStream InMemoryStream { get; }
public MyReaderStream(string path)
{
InMemoryStream = GetInputFile(path);
//if (InMemoryStream == null) throw new MyReaderException($"path {path} could not be found");
if (InMemoryStream == null) InMemoryStream = new MemoryStream();
}
public MyReaderStream(MemoryStream stream)
{
InMemoryStream = stream;
if (InMemoryStream == null) InMemoryStream = new MemoryStream();
}
public void Dispose()
{
InMemoryStream?.Dispose();
}
public bool VerifyPath(string path)
{
var extension = Path.GetExtension(path);
if (extension != null && !extension.Equals(@".bin")) return false;
return File.Exists(path);
}
public MemoryStream GetInputFile(string path)
{
if (!VerifyPath(path)) return null;
MemoryStream inMemoryCopy = new MemoryStream();
using (FileStream fs = File.OpenRead(path))
{
fs.CopyTo(inMemoryCopy);
}
return inMemoryCopy;
}
}
public class MyReader
{
private readonly IMyReaderStream _stream;
private uint? offset = null;
public MyReader(IMyReaderStream stream)
{
this._stream = stream ?? new MyReaderStream(new MemoryStream());
}
public uint? GetKey()
{
try
{
offset = Helpers.ReadWord(_stream.InMemoryStream, 0);
//might fail if file is corrupted
}
catch(Exception) {return null;}
}
public uint? FirstDependedMethod(){
return Helpers.ReadWord(_stream.InMemoryStream, offset + SOME_CONSTANT1); //if offset is null...?
}
//more methods like FirstDependedMethod
//.....
//.....
}
更新
这是一个WPF MVVM项目。模型看起来像这样:
[NotifyPropertyChanged]
public class Model
{
private NvmReader _reader;
public Model()
{
Reader = new NvmReader(null);
}
public NvmReader Reader
{
set { _reader = value; }
get { return _reader; }
}
}
并由ViewModel
初始化,如下所示:
this._model = new Model();
当用户选择二进制文件的路径时,NvmReader
对象才能获得所需的偏移量
答案 0 :(得分:1)
您应该将班级分为两类。
假设您从课程开始
public class MyClass
{
public void Initialize(int value)
{
}
public void MethodA() { }
public void MethodB() { }
}
MethodA
和MethodB
都要求首先调用Initialize
方法。
您可以将此类重构为2个单独的类。一个将负责实现MethodA
和MethodB
,另一个负责初始化。这样,类型系统将确保所有内容都已初始化。
public class MyClassFactory
{
public MyClass Create(int value)
{
return new MyClass(value);
}
}
public class MyClass
{
internal MyClass(int value)
{
}
public void MethodA() { }
public void MethodB() { }
}