The cleanest way might be to implement an indexer. That way you can switch a single time, do whatever checks on the language, handle issues, deal with defaults, etc. inside the Caption class without the ceremony of calling a method, like so:
class Caption
{
public string AR { get; set; }
public string EN { get; set; }
public string Tu { get; set; }
// var cap = new Caption()[language];
public string this[string language]
{
get
{
var which = AR;
switch(language)
{
case nameof(EN):
which = EN;
break;
case nameof(Tu):
which = Tu;
break;
}
return which;
}
}
}
Note that it's possible to achieve the syntax you're after where you can implicitly convert a Caption to a string. The caveat is that you'd need to know the language at some point before you do the conversion.
You can do so by providing a constructor that handles it on creation and/or with a method (chain-able if you wish) like I do below with For:
class Caption
{
public string AR { get; set; }
public string EN { get; set; }
public string Tu { get; set; }
// Gets the caption of the current language
public string Current { get; private set; }
// If the language is known in advance, you can return
// the desired language directly.
public static implicit operator string(Caption caption)
=> caption.Current;
public Caption For(string language)
{
var which = AR;
switch (language)
{
case nameof(EN):
which = EN;
break;
case nameof(Tu):
which = Tu;
break;
}
Current = which;
return this;
}
}
// Usage
var cap = new Caption
{
AR = "Test-ar",
EN = "Test-en",
Tu = "Test-tu"
}.For("EN");
string s = cap;
Console.WriteLine(s); // Test-en
CultureInfoargument. OverrideToString()to return the Caption in the language specified in the constructor. You can store all the strings corrensponding to a text in a specific culture in a Dictionary instead of using a public property for each culture. It's easier to load from a JSON file, too.