0

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);

LorneCash
  • 1,446
  • 2
  • 16
  • 30
  • Does [this](https://stackoverflow.com/q/50811750/5133585) answer your question? One of the non-accepted answers shows your how to get the value of property. – Sweeper Aug 24 '22 at 02:21
  • 3
    You want `CallerArgumentExpression` https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/caller-information ? – Jeremy Lakeman Aug 24 '22 at 05:00

1 Answers1

0

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.

LorneCash
  • 1,446
  • 2
  • 16
  • 30