Обработка переопределения для базовых / примитивных типов в области видимости - PullRequest
0 голосов
/ 07 февраля 2012

Я хотел бы иметь возможность создавать код, который выглядит следующим образом:

30, 60, 90

И пусть получится List<int> с этими числами в нем. Проблема в том, что для этого я считаю, что мне нужно иметь возможность переопределить работу int в этой области. Есть ли какой-нибудь способ, которым я мог бы иметь свой собственный класс "Int", который мог бы использоваться в определенной области видимости всякий раз, когда вводилась примитивная константа, такая как 30? Если я не могу переопределить int, тогда класс должен использоваться явно в этой области, и в итоге я получу что-то вроде этого:

Int(30),Int(60),Int(90)

Что еще меньше кода, чем стандартный способ:

var nums = new List<int>(); nums.Add(30); nums.Add(60); nums.Add(90);

или даже:

var nums = new List<int>{ 30, 60, 90 };

Я играю со своим собственным языком сценариев, только для образовательных целей, не предназначенным для кого-либо еще. Я пытаюсь понять, насколько я могу упростить синтаксис, чтобы читать ближе к естественному языку. Возможно ли что-то вроде первого блока кода в верхней части этого вопроса? Если это возможно, могу ли я распространить его на другие примитивные типы?

РЕДАКТИРОВАТЬ: я хочу что-то, что является чистым C #, я не делаю мой собственный анализ или писать свой собственный компилятор. Мне интересно, можно ли каким-то образом использовать примитивный тип, такой как константа int, вместо этого через мой собственный тип? Я не думаю, что это возможно, но если не по крайней мере, StackOverflow хорош в предоставлении альтернатив, о которых я, возможно, и не думал.

Хорошо, вот что я придумал, чтобы приблизить меня:

public static class Values
{
    static public List<int> Make(params int[] vals)
    {
        return vals.ToList();
    }
}

Это позволяет мне сделать что-то вроде:

var nums = Values.Make(30, 60, 90);

Конечно, это не намного короче, чем var nums = new List<int>{ 30, 60, 90 };, но это позволяет мне абстрагировать int, чтобы они также могли делать:

var nums = Values.Make(30.0f, 60.0f, 90.0f);

Пока я создаю обработчик для списка поплавков. К сожалению, если я сделаю общий метод, например, так:

public static List<T> Make<T>(params T[] vals) where T : IComparable<T>
{
    return vals.ToList();
}

Тогда это сделает синтаксис более длинным:

var nums = Values.Make<float>(30.0f, 60.0f, 90.0f);

Ответы [ 2 ]

3 голосов
/ 07 февраля 2012

Если вы находитесь на C # 4.0, вы можете упростить его до:

var nums = new[] { 30, 60, 90 };

, что создаст int[].Это также может быть использовано с другими типами:

var floats = new[] { 30.0f, 60.0f, 90.0f };

Если вам действительно нужен List<T>, то вы можете сделать:

var nums = new[] { 30, 60, 90 }.ToList();
2 голосов
/ 07 февраля 2012

У Smoak был самый чистый и эффективный способ реализации конкретной ситуации, которую я описывал, но если вы хотите посмотреть, как вы можете переопределить обработку для базовых примитивных типов, вот пример.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        // This lets you add new functionality to the primitive type 'int'
        // Allowing you to do (10).Add(5) to give you a List<int> with {10, 5}
        public static List<int> And( this int num, int other )
        {
            return new List<int> { num, other };
        }

        public static List<int> And( this List<int> num, int other )
        {            
            num.Add(other);
            return num;
        }
    }
}

// ===========================================================================
// And Program.cs
using ExtensionMethods;

namespace SyntaxTests
{
    class Program
    {
        static void Main( string[] args )
        {            
            var nums = (30).And(60).And(90);

            nums.ForEach(n => Console.WriteLine(n + "\n"));
        }
    }
}

С выводом, который выглядит как:

30

60

90

Помимо того, что он менее элегантен, чем ответ Смока, он также менее эффективен: эта строка кода var nums = (30).And(60).And(90); создает целое число, затем создает список с двумя целыми числами, а затем создает список с тремя целыми числами, тогда как var nums = new[] {30, 60, 90}; просто составляет список с тремя целыми числами.

...