作为泛型类型传递的访问类属性
本文关键字:访问 属性 泛型类型 | 更新日期: 2023-09-27 18:00:29
我有两个类,它们被传递给Serialization方法,我想在Serialization方法中访问这些类的两个属性。问题是序列化方法参数是作为泛型类型传递的,在这种情况下,我不知道如何访问传递类的属性。下面的例子。
public class MyClass1
{
public string MyProperty1 { get; set; }
//These properties are shared in both classes
public bool Result { get; set; }
public string EngineErrorMessage { get; set; }
}
public class MyClass2
{
public string MyProperty2 { get; set; }
//These properties are shared in both classes
public bool Result { get; set; }
public string EngineErrorMessage { get; set; }
}
//The method is used to serialize classes above, classes are passed as generic types
public void Serialization<T>(ref T engine)
{
try
{
//Do some work with passed class
}
catch (Exception e)
{
//If Exception occurs I would like to write values to passed class properties, how to do that?
Result = false;
EngineErrorMessage = e.Message;
}
}
完整方法代码
public void Submit<T>(ref T engine)
{
try
{
var workingDir = Path.Combine(Settings.FileStoragePath, Helpers.GetRandomInt(9).ToString());
Directory.CreateDirectory(workingDir);
var inputFile = Path.Combine(workingDir, Settings.InFileName);
var outputFile = Path.Combine(workingDir, Settings.OutFileName);
var deleteFile = Path.Combine(workingDir, Settings.DelFileName);
try
{
using (var stream = new FileStream(inputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
Serializer.Serialize(stream, engine);
}
CheckStatus(outputFile);
using (var stream = new FileStream(outputFile, FileMode.Open, FileAccess.Read, FileShare.None))
{
engine = Serializer.Deserialize<T>(stream);
}
}
finally
{
File.Create(deleteFile).Dispose();
}
}
catch (Exception e)
{
//ToDo: Not implemented yet.
/* Result = false;
ErrorMessage = e.Message;*/
}
}
声明一个包含属性Result
和EngineErrorMessage
的接口。现在您有两个选项:
- 向序列化类型参数添加约束,以便只能序列化从上述接口派生的类型,或者
- 在您的catch块中,尝试将
engine
强制转换为上面提到的接口。如果强制转换成功,请编写属性值,否则不执行任何操作
样品:
public interface ISerializationErrorWriter
{
bool Result { set; get; }
string EngineErrorMessage { set; get; }
}
public class MyClass1 : ISerializationErrorWriter
{
public string MyProperty1 { get; set; }
public bool Result { get; set; }
public string EngineErrorMessage { get; set; }
}
public class MyClass2 : ISerializationErrorWriter
{
public string MyProperty2 { get; set; }
public bool Result { get; set; }
public string EngineErrorMessage { get; set; }
}
// Option 1:
public void Serialization_1<T>(ref T engine) where T : ISerializationErrorWriter
{
try
{
//Do some work with passed class
}
catch (Exception e)
{
engine.Result = false;
engine.EngineErrorMessage = e.Message;
}
}
// Option 2:
public void Serialization_2<T>(ref T engine)
{
try
{
//Do some work with passed class
}
catch (Exception e)
{
var serializationErrorWriter = engine as ISerializationErrorWriter;
if(serializationErrorWriter != null)
{
serializationErrorWriter.Result = false;
serializationErrorWriter.EngineErrorMessage = e.Message;
}
}
}
您将不得不在某个时刻通过typeof(T)
(或engine.GetType()
)使用反射。如果这是一个频繁的代码路径,您可能希望按类型缓存某种策略以避免开销。或者更好的方法是:使用预先构建的序列化API来优化这种类型的场景(即大多数场景)。
如果你指的是Result
和EngineErrorMessage
,那么有两个选项:
- 将这两个属性放在一个接口上,从t2类型实现该接口,并将
where T : ISomeInterface
约束添加到Serialization<T>
- 使用
dynamic
将类型转移到属性
如果您只有两个类要处理,我认为下面的序列化代码可以很好地为您提供
//The method is used to serialize classes above, classes are passed as generic types
public void Serialization<T>(ref T engine)
{
try
{
Type genericType = typeof(T);
if (typeof(MyClass1).Equals(genericType))
{
MyClass1 engineClass1 = engine as MyClass1;
//DO something for class 1
}
else if (typeof(MyClass2).Equals(genericType))
{
MyClass2 engineClass2 = engine as MyClass2;
//DO something for class 2
}
}
catch (Exception e)
{
//If Exception occurs I would like to write values to passed class properties, how to do that?
Result = false;
EngineErrorMessage = e.Message;
}
}