I have a method where I'm currently passing in both someObject
and nameof(someObject)
since I'm using this method many times I'm wanting to simplify my code by finding a way to only pass in the object once but if I do the nameof() inside the method I'm obviously not going to get the name I want.
What I have currently is something like this:
public record ResourceObject
{
public string Name { get; init; }
public byte[] File { get; init; }
public string Content { get; init; }
public ResourceObject(string name, byte[] file)
{
Name = name;
File = file;
Content = Encoding.Default.GetString(file);
}
}
Where the use looks like this:
var test = new ResourceObject(nameof(Properties.Resources.SomeResource), Properties.Resources.SomeResource)
Ideally, I'd like to get the use to look like this(I don't think this is possible):
var test = new ResourceObject(Properties.Resources.SomeResource)
I did find a post that shows getting the name like this but then I can't get the object itself:
public record ResourceObject
{
public string Name { get; init; }
public byte[] File { get; init; }
public string Content { get; init; }
private ResourceObject(string name, byte[] file)
{
Name = name;
File = file;
Content = Encoding.Default.GetString(file);
}
public static ResourceObject New<T>(Expression<Func<T>> property)
{
var name = (property.Body as MemberExpression).Member.Name;
var file = ???; //I can't figure out how to get the object itself here
return new(name, file);
}
}
The use for that looks like this (which would be great improvement over what I if I could get it to work):
var test = ResourceObject.New(() => Resources.TradeEngineSettings_Base);
This is what ultimately worked for me.
public record ResourceObject<T>
{
public string Name { get; }
public T Object { get; }
public string Content { get; }
public ResourceObject(T @object, [CallerArgumentExpression(nameof(@object))] string name = null)
{
Name = name.Split('.', StringSplitOptions.RemoveEmptyEntries)[^1];
Object = @object;
if (@object?.GetType() == typeof(byte[]))
{
Content = Encoding.Default.GetString(@object as byte[] ?? Array.Empty<byte>());
}
}
}
To keep Name
more similar to a nameof()
behavior, name
is split on '.' and only takes the last item in the array.