Add nullable annotations and update class constructors. Improve XML deserialization handling.

This commit is contained in:
Marc Hernandez 2024-05-26 18:47:11 -07:00
parent 05656d469a
commit 4e59ae0331
6 changed files with 56 additions and 71 deletions

View File

@ -18,7 +18,7 @@
</PropertyGroup>
<PropertyGroup>
<NoWarn>$(NoWarn);SYSLIB0050;CS8981</NoWarn>
<NoWarn>$(NoWarn);SYSLIB0050;CS8981; CS8632</NoWarn>
</PropertyGroup>
<ItemGroup>

View File

@ -1,4 +1,9 @@
using System;

#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
@ -13,7 +18,6 @@ using lib;
namespace imm;
/*
T O D O :
T O D O :
@ -21,7 +25,6 @@ T O D O :
x) Add unit tests for all this. This will definitely benefit from them
*/
static public class Util
{
//This can handle both Timed and Recorded
@ -30,7 +33,7 @@ static public class Util
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("fn")]
string dbgExp = default )
string dbgExp = "" )
where T : Recorded<T>
{
obj = obj.Process( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );
@ -43,7 +46,7 @@ static public class Util
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("fn")]
string dbgExp = default
string dbgExp = ""
)
where T : Versioned<T>
{
@ -81,7 +84,7 @@ public interface Imm
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("next")]
string dbgExp = default
string dbgExp = ""
)
{
return next;
@ -210,7 +213,7 @@ public record class Recorded<T> : Versioned<T>, imm.Imm
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
new public MetaData Meta => MetaStorage as MetaData;
new public MetaData Meta => MetaStorage as MetaData ?? new MetaData();
override public T Record(
@ -229,7 +232,7 @@ public record class Recorded<T> : Versioned<T>, imm.Imm
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("next")]
string dbgExp = default
string dbgExp = ""
)
{
return ProcessWork( ( old ) => next, reason, dbgName, dbgPath, dbgLine, dbgExp );
@ -242,7 +245,7 @@ public record class Recorded<T> : Versioned<T>, imm.Imm
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("fn")]
string dbgExp = default
string dbgExp = ""
)
{
return ProcessWork( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );
@ -329,7 +332,7 @@ public record class Timed<T> : Recorded<T>, imm.Imm
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("next")]
string dbgExp = default
string dbgExp = ""
)
{
return ProcessWork( ( old ) => next, reason, dbgName, dbgPath, dbgLine, dbgExp );
@ -341,7 +344,7 @@ public record class Timed<T> : Recorded<T>, imm.Imm
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("next")]
string dbgExp = default
string dbgExp = ""
)
where U : T
{
@ -354,7 +357,7 @@ public record class Timed<T> : Recorded<T>, imm.Imm
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("fn")]
string dbgExp = default
string dbgExp = ""
)
=> ProcessWork( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );

View File

@ -1,3 +1,6 @@
#nullable enable
using System;
using System.Runtime.Serialization;
using System.Net.Sockets;

View File

@ -77,20 +77,11 @@ public class Ref : lib.I_Serialize
[Serializable]
[DebuggerDisplay("Path = {path} / Res = {res}")]
public class Ref<T> : Ref where T : class
public class Ref<T> : Ref where T : class, new()
{
public T? res => m_res != null ? m_res : lookup();
public T res => m_res != null ? m_res : lookup();
/*
override public T? lookup()
{
m_res = Mgr.load<T>( Filename );
if( s_verboseLogging ) log.info( $"Ref.lookup {GetType().Name} {GetType().GenericTypeArguments[0]} path {Filename}" );
return m_res;
}
*/
override public T? lookup(
override public T lookup(
string reason = "",
[CallerMemberName] string dbgName = "",
[CallerFilePath] string dbgPath = "",
@ -170,39 +161,13 @@ public class Ref<T> : Ref where T : class
[NonSerialized]
protected T m_res;
}
/*
public class RefMemory<T> : Ref<T> where T : class
{
//For serialization
public RefMemory( T res )
:
base( "{memory}" )
{
m_res = res;
}
override internal void load()
{
}
}
*/
public class Resource
{
static public Mgr mgr;
}
public delegate T Load<out T>( string filename );
@ -237,9 +202,9 @@ where T : class
}
//generic classes make a new static per generic type
class ResCache<T> where T : class
class ResCache<T> where T : class, new()
{
public static T s_default = default;
public static T s_default = new();
public static ImmutableDictionary<string, ResourceHolder<T>> s_cache = ImmutableDictionary<string, ResourceHolder<T>>.Empty;
}
@ -314,7 +279,7 @@ public class Mgr
[CallerMemberName] string dbgName = "",
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = 0
) where T : class
) where T : class, new()
{
return new Ref<T>( filename, reason, dbgName, dbgPath, dbgLine );
}
@ -360,11 +325,10 @@ public class Mgr
[CallerLineNumber] int dbgLine = 0,
[CallerArgumentExpression("fn")]
string dbgExp = default
) where T : class
) where T : class, new()
{
if( ResCache<T>.s_cache.TryGetValue( filename, out var holder ) )
{
if( holder.weak.TryGetTarget( out var v ) )
{
return v;
@ -385,7 +349,7 @@ public class Mgr
return newV;
}
static public T actualLoad<T>( string filename ) where T : class
static public T actualLoad<T>( string filename ) where T : class, new()
{
lock(s_loading)
{

View File

@ -1,5 +1,6 @@

#nullable enable

View File

@ -1,4 +1,7 @@
using System;

using System;
using System.IO;
using System.Xml;
using System.Runtime.Serialization;
@ -184,32 +187,41 @@ namespace lib
void SetFromStr( Stream stream )
{
fromStr = stream.ToString();
fromStr = string.IsNullOrWhiteSpace(fromStr) ? (stream as FileStream).Name : fromStr;
fromStr = string.IsNullOrWhiteSpace(fromStr) ? (stream as NetworkStream).Socket.RemoteEndPoint.ToString() : fromStr;
fromStr = stream.ToString() ?? "{null}";
if( stream is FileStream fs )
{
fromStr = fs.Name;
}
if( stream is NetworkStream ns )
{
fromStr = ns?.Socket?.RemoteEndPoint?.ToString() ?? $"{ns}";
}
}
public object Deserialize( Stream stream )
{
SetFromStr( stream );
return DeserializeKnownType( stream, null );
var obj = DeserializeKnownType( stream, null );
return obj;
}
public T Deserialize<T>( Stream stream ) => (T)DeserializeKnownType( stream, typeof( T ) );
public T? Deserialize<T>( Stream stream ) => (T)DeserializeKnownType( stream, typeof( T ) );
public object DeserializeKnownType( Stream stream, Type t )
public object? DeserializeKnownType( Stream stream, Type? t )
{
SetFromStr( stream );
XmlTextReader reader = new( stream );
object obj = Deserialize( reader, t );
object? obj = Deserialize( reader, t );
return obj;
}
private object Deserialize( XmlReader reader, Type t )
private object? Deserialize( XmlReader reader, Type? t )
{
m_alreadySerialized.Clear();
m_objectID = new ObjectIDGenerator();
@ -220,6 +232,8 @@ namespace lib
doc.Load( reader );
if( doc.DocumentElement == null ) return null;
if( t == null )
return Deserialize( doc.DocumentElement );
@ -276,13 +290,13 @@ namespace lib
static private bool IsEnumerable( Type type ) => type.IsAssignableTo( typeof( IEnumerable ) );
private object Deserialize( XmlElement elem, MemberInfo mi, Type type, object existing /*, object enclosing = null*/ )
private object Deserialize( XmlElement elem, MemberInfo? mi, Type type, object? existing /*, object enclosing = null*/ )
{
var name = mi?.Name ?? "{NOT_FOUND}";
return Deserialize( elem, mi, type, name, existing );
}
private object Deserialize( XmlElement elem, MemberInfo mi, Type type, string name, object existing /*, object enclosing = null*/ )
private object Deserialize( XmlElement elem, MemberInfo? mi, Type type, string name, object? existing /*, object enclosing = null*/ )
{
try
{