#c# #generics #generic-constraints #generic-interface #generic-type-parameters
Вопрос:
Мне нужно создать интерфейс с типом 2 и использовать его в качестве возвращаемого значения метода.
public interface StringLong<T1,T2>
where T1 : string
where T2 : long
{}
StringLong<T1,T2> method StringLong<T1,T2>()
Комментарии:
1. @OlivierRogier : вывод метода иногда бывает строковым, а иногда длинным или, возможно, другими типами в будущем.
2. @OlivierRogier — Хороший вопрос. Я надеюсь, что оперативная группа сможет ответить на этот вопрос в ближайшее время.
3. @OlivierRogier — Пожалуйста, избегайте редактирования ответов других людей и добавления информации. Решение о добавлении информации зависит от автора. Вместо этого лучше всего опубликовать запрос на дополнительную информацию в качестве комментария.
4. Я знаю, что мы можем использовать словарь или кортеж, но мне нужен универсальный интерфейс
5. Аргумент «мне нужно» немного слаб. Не могли бы вы, пожалуйста, объяснить, почему вы так думаете?
Ответ №1:
Нет смысла определять интерфейс с двумя универсальными типами, которые вы ограничиваете только string
и long
.
Похоже, вам просто нужен кортеж:
(string, long) MyMethod()
{
return ("Hello", 42L);
}
Вы даже можете назвать возвращаемые значения:
(string message, long meaningOfLife) MyMethod()
{
return ("Hello", 42L);
}
Тогда вы сможете написать:
var result = MyMethod();
Console.WriteLine(result.message);
Console.WriteLine(result.meaningOfLife);
Ответ №2:
Я думаю, что это функциональность, которую вы пытаетесь достичь (из комментариев). Так как возвращение может string
быть либо long
от одного, либо от общего предка object
.
Как только у вас будет значение, вы можете использовать сопоставление с образцом, чтобы привести результат к соответствующему типу:
static class Program
{
static void Main(string[] args)
{
var obj = MethodReturnsStringOrLong(1722);
switch (obj)
{
case string str:
Console.WriteLine($"String is {str}");
break;
case long lng:
Console.WriteLine($"Long is {lng}");
break;
default:
throw new NotSupportedException();
}
}
public static object MethodReturnsStringOrLong(int input)
{
if (input % 2 == 0)
{
return 1928374028203384L;
}
else
{
return "ASIDJMFHSOASKSJHD";
}
}
}
Альтернативой является создание собственного общего предка, например, класса Value
ниже, который может содержать либо a long
и/или a string
.
public class Value
{
public Value(long longValue)
{
LongValue = longValue;
}
public Value(string stringValue)
{
StringValue = stringValue;
}
public long? LongValue { get; }
public string StringValue { get; }
}
static class Program
{
static void Main(string[] args)
{
var obj = MethodReturnsStringOrLong(1722);
if (obj.LongValue.HasValue)
{
Console.WriteLine($"Long is {obj.LongValue.Value}");
}
if (!string.IsNullOrEmpty(obj.StringValue))
{
Console.WriteLine($"String is {obj.StringValue}");
}
}
public static Value MethodReturnsStringOrLong(int input)
{
if (input % 2 == 0)
{
return new Value(1928374028203384L);
}
else
{
return new Value("ASIDJMFHSOASKSJHD");
}
}
}