Виртуальные дополнительные методы?

Вот часть моего проекта, которая изменяет размер текста в зависимости от размера экрана. Это то, что вы хотите?

double height;
double width = parent.getMeasuredWidth();

boolean isLandscape;
if ( getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ) {
    isLandscape = false;
    height = parent.getMeasuredHeight() / 3;
    width = width + (parent.getPaddingLeft() + parent.getPaddingRight());
} else {
    isLandscape = true;
    height = parent.getMeasuredHeight() / 2;
    width = parent.getMeasuredWidth() / 2;
    width = width + ((parent.getPaddingLeft() + parent.getPaddingRight()) / 2);
}       

height = height + (parent.getPaddingTop() + parent.getPaddingBottom());

view.setMinimumHeight((int) Math.round(height));

double h = height / 100;
double w = width / 100; 

if ( isLandscape ) {
    textViewService.setX((int) Math.round(w * 24));
    textViewService.setTextSize(TypedValue.COMPLEX_UNIT_PX, (int) Math.round(16 * h));
} else {
    textViewService.setX((int) Math.round(w * 23));
    textViewService.setTextSize(TypedValue.COMPLEX_UNIT_PX, (int) Math.round(18 * h));
}
12
задан user 29 May 2012 в 18:35
поделиться

5 ответов

Нет, таких методов виртуального расширения не существует. Вы можете использовать перегрузку, но это не поддерживает полиморфизм. Звучит так, как будто вы захотите взглянуть на что-то вроде внедрения зависимостей (и т. Д.), Чтобы в разных средах был добавлен другой код (зависимости), и использовать его в обычных виртуальных методах: Реализация ISomeUtility для B во время выполнения. Вы можете сделать то же самое с центральным статическим реестром (IOC, но без DI):

    override void Execute() {
        ISomeUtility util = Registry.Get<ISomeUtility>();
        if(util != null) util.Foo();
    }

(где вам нужно написать реестр и т. Д .; плюс на сервере, зарегистрировать реализацию ISomeUtility )

4
ответ дан 2 December 2019 в 22:38
поделиться

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

using System;
using System.Collections.Generic;

namespace LanguageTests2
{
    public class A { }

    public class B : A {}

    public class C : B {}

    public static class VirtualExtensionMethods
    {
        private static readonly IDictionary<Type,Action<A>> _dispatchMap 
            = new Dictionary<Type, Action<A>>();

        static VirtualExtensionMethods()
        {
            _dispatchMap[typeof(A)] = x => ExecuteInternal( (A)x );
            _dispatchMap[typeof(B)] = x => ExecuteInternal( (B)x );
            _dispatchMap[typeof(C)] = x => ExecuteInternal( (C)x );
        }

        public static void Execute( this A instance )
        {
            _dispatchMap[instance.GetType()]( instance );
        }

        private static void ExecuteInternal( A instance )
        {
            Console.WriteLine("\nCalled ToString() on: " + instance);
        }

        private static void ExecuteInternal(B instance)
        {
            Console.WriteLine( "\nCalled ToString() on: " + instance );
        }

        private static void ExecuteInternal(C instance)
        {
            Console.WriteLine("\nCalled ToString() on: " + instance);
        }
    }

    public class VirtualExtensionsTest
    {
        public static void Main()
        {
            var instanceA = new A();
            var instanceB = new B();
            var instanceC = new C();

            instanceA.Execute();
            instanceB.Execute();
            instanceC.Execute();
        }
    }
}
2
ответ дан 2 December 2019 в 22:38
поделиться

Виртуальное наследование подразумевает ООП, а методы расширения являются «просто» статическими методами, которые через синтаксический сахар Компилятор позволяет вам делать вид, что вызывает экземпляр типа его первого параметра. Так что нет, о виртуальных методах расширения не может быть и речи.

Проверьте ответ Марка Гравелла для возможного решения вашей проблемы.

0
ответ дан 2 December 2019 в 22:38
поделиться

Вы можете создать сервисный регистр. Пример (на стороне сервера):

static IDictionary<Type, IService> serviceRegister;

public void ServerMethod(IBusinessType object)
{
  serviceRegister[obect.GetType()].Execute(object);
}

Вам нужны скорее службы на вашем сервере, которые реализуют функциональность на стороне сервера, а не методы расширения. Я бы не стал придавать много логики методам расширения.

0
ответ дан 2 December 2019 в 22:38
поделиться

Позвольте мне проверить: у вас есть иерархия классов, наследуемая от A, предположительно структурированная в соответствии с вашей бизнес-областью. Затем вы хотите добавить поведение в зависимости от того, где выполняются классы. До сих пор вы использовали методы расширения, но теперь вы обнаружите, что не можете заставить их варьироваться в зависимости от вашей иерархии классов. Какие виды поведения вы применяете на сервере?

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

В любом случае, похоже, что вам понадобится тщательная разработка и тестирование стратегии тестирования, так как вы вводите вариации по двум одновременным измерениям (иерархия наследования, среда выполнения). Вы пользуетесь юнит-тестированием? Убедитесь, что любое решение, которое вы выберете (например, DI через конфигурацию), хорошо взаимодействует с тестированием и макетом.

Вам потребуется тщательный дизайн тестируемости и стратегия тестирования, так как вы вводите вариации по двум одновременным измерениям (иерархия наследования, среда выполнения). Вы пользуетесь юнит-тестированием? Убедитесь, что любое решение, которое вы выберете (например, DI через конфигурацию), хорошо взаимодействует с тестированием и макетом.

Вам потребуется тщательный дизайн тестируемости и стратегия тестирования, так как вы вводите вариации по двум одновременным измерениям (иерархия наследования, среда выполнения). Вы пользуетесь юнит-тестированием? Убедитесь, что любое решение, которое вы выберете (например, DI через конфигурацию), хорошо взаимодействует с тестированием и макетом.

0
ответ дан 2 December 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: