Is it possible to pass interpolated strings as parameter to a method?

前端 未结 4 499
一整个雨季
一整个雨季 2021-01-04 13:33

I have started to use Interpolated Strings (new feature of C# 6) and it is really useful and gracefully. But according to my needs I have to pass format of string to a metho

相关标签:
4条回答
  • 2021-01-04 13:46

    It is not possible. But the alternate way is

    public static string MyMethod(string format, params object[] args)
    {
      if (format == null || args == null)
        throw new ArgumentNullException(format == null ? "format" : "args");
      return string.Format((IFormatProvider) null, format, args);
    }
    

    EDIT:

    MyMethod("The number is {0}", 12);
    

    EDIT2:

    public static string MyMethod(string format)
    {
        var i = 12;
        var result = string.Format(null, format, i);
        return result;
    }
    MyMethod("{0:000}");
    
    0 讨论(0)
  • 2021-01-04 13:51

    There are several ways you can do this.

    The first one is to add another method overload that takes a FormattableString (a new typed used by one of the variants of string interpollation) and calls the original one:

    public void MyMethod(FormattableString fs)
    {
        MyMethod(fs.Format);
    }
    

    And you also have access to the arguments if you need to.

    If you only need the format, just create an extension method to extract it:

    public static string AsFormat(FormattableString fs)
    {
        return fs.Format;
    }
    
    0 讨论(0)
  • 2021-01-04 13:59

    You cannot do that, and that would not be a very good idea either - it means you are using local variables from another method.
    This would defeat the purpose of this feature - to have compiler verifiable string interpolation and binding to local variables.

    C# has several good alternatives. For example, using a Func:

    public void MyMethod(Func<int,string> formatNumber)
    {
        int i = 3;
        var formatted = formatNumber(i);
    }
    

    use as:

    MyMethod(number => $"AAA{number:00}");
    

    This is better than what you have today - where you have the format string(s?) and its usage in different places.

    If you have more than a single variable this approach can scale, but consider grouping them into a class (or a struct) - the func will look much better, and your code will be more readable. This class can also override .ToString(), which might be useful for you.

    Another simple option is to pass just the format: MyMethod("00") and i.ToString(format), but that only works in your presumably simplified example.

    0 讨论(0)
  • 2021-01-04 14:03

    Several years since this was asked however I came across this via Google while searching for an answer that I already had in my head, but couldn't get my mind around the implementation/syntax.

    My solution is further to what @Kobi supplied...

    public class Person
        {
            public int Id {get; set;}
            public DateTime DoB {get;set;}
            public String Name {get;set;}
        }
    
    public class MyResolver
    {
        public Func<Person, string> Resolve {get;set;}
        public string ResolveToString<T>(T r) where T : Person
        {
            return this.Resolve(r);
        }
    }
    
    // code to use here...
    var employee = new Person();
    employee.Id = 1234;
    employee.Name = "John";
    employee.DoB = new DateTime(1977,1,1);
    
    var resolver = new MyResolver();
    resolver.Resolve = x => $"This person is called {x.Name}, DoB is {x.DoB.ToString()} and their Id is {x.Id}";
    
    Console.WriteLine(resolver.ResolveToString(employee));
    

    I haven't tested the above for syntax errors but hopefully you get the idea and you can now just define "how" you want the string to look but leave the blanks to be filled in at runtime depending upon the values in your Person object.

    Cheers,

    Wayne

    0 讨论(0)
提交回复
热议问题