Используя интерфейс для преобразования объекта от одного типа до другого?

Это старая и известная проблема, появившаяся в React Router v4, и в настоящее время она (AFAIK) не решена.

К счастью, обойти это довольно легко, используя пользовательский объект истории (то, что вы бы сделали, если вы хотите синхронизировать состояние Redux с историей браузера). Настоящий производственный код должен быть более надежным, чем то, что я пишу здесь, но вы можете начать с этого:

a) Прежде всего используйте <Router> вместо <BrowserRouter>.

import { Router, Route, Link } from "react-router-dom";

b) Создает свой собственный объект истории (не забудьте npm add history, если вы этого не сделали):

import createBrowserHistoryfrom "history/createBrowserHistory";

// ...

const history = createBrowserHistory();

c) Замените метод push() вашей собственной реализацией: [ 1114]

const originalHistoryPush = history.push;

history.push = function(path, state = {}) {
    if (!this.location) {
        originalHistoryPush(path, state);
        return;
    }

    const oldPath = this.location.pathname + this.location.search + this.location.hash;
    if (oldPath !== path || !shallowEqual(state, this.location.state)) {
        originalHistoryPush(path, state);
    } else {
        this.replace(path, state);
    }
};

d) Используйте пользовательскую историю :

<Router history={history}>...</Router>

Обратите внимание, что для сравнения я использую гипотетический метод shallowEqual(). Вы можете быстро написать свою собственную или выбрать одну из множества реализаций.

9
задан Jason Baker 19 November 2008 в 22:21
поделиться

8 ответов

"Вы смогли бы дать мне пример того, как я могу сделать это (или по крайней мере указать на меня к правильным методам для использования)? Я, кажется, не могу найти их на MSDN" – Jason Baker

Jason, что-то как следующее:

var props = typeof(Foo)
            .GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach (PropertyInfo p in props)
{
     // p.Name gives name of property
}

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

3
ответ дан 4 December 2019 в 06:31
поделиться

Можно создать неявные операторы в каждом классе, чтобы сделать преобразование для Вас:

public class SomeClass
{
    public static implicit operator SomeOtherClass(SomeClass sc)
    {
        //replace with whatever conversion logic is necessary
        return new SomeOtherClass()
        {
            foo = sc.foo,
            bar = sc.bar
        }
    }

    public static implicit operator SomeClass(SomeOtherClass soc)
    {
        return new SomeClass()
        {
            foo = soc.foo,
            bar = soc.bar
        }
    }
    //rest of class here
}

и затем SomeOtherClass soc = sc; и наоборот работал бы.

9
ответ дан 4 December 2019 в 06:31
поделиться

Разве точка интерфейса не, чтобы не должной быть сделать это? Вы делаете что-то с конкретной реализацией SomeOtherClass? Вместо того, чтобы использовать конкретную реализацию, используйте интерфейс, и не должно иметь значения при использовании класса SomeClass или SomeOther.

Кроме этого, лучшее, которое Вы могли сделать, должно записать своего рода функция помощника (необходимо было бы все еще сделать это вручную или изучить отражение), который копирует каждое Свойство в Интерфейсе, который был бы похож на это:

   public ISomeInterface CopyValues(ISomeInterface fromSomeClass, ISomeInterface toSomeOtherClass)
   {
    //copy properties here
    return toSomeOtherClass;
    }

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

6
ответ дан 4 December 2019 в 06:31
поделиться

Отражение... цикл через каждое свойство и набор это на соответствующем свойстве на другом объекте.

4
ответ дан 4 December 2019 в 06:31
поделиться

разве это не работало бы?

class MyClass : ICloneable
{
public MyClass()
{

}
public object Clone() // ICloneable implementation
{
MyClass mc = this.MemberwiseClone() as MyClass;

return mc;
}

Только необходимо звонить: MyClass. Клон ().

3
ответ дан 4 December 2019 в 06:31
поделиться

Проверьте ответ Joe для Отражательного решения.

Я предполагаю, что Вы используете Visual Studio.

Действительно ли Вы знакомы с ctrl+shift+r и ctrl+shift+p ярлыками? В противном случае ctrl+shift+r начинает/заканчивает записывать макрос нажатия клавиши. ctrl+shift+p играет зарегистрированный макрос.

То, что я сделал, когда я установил много свойств, должно скопировать объявления свойства туда, где я хочу, чтобы они были установлены и записали макрос для видоизменения объявления к оператору набора и перемещению курсора к следующей строке, затем я просто играю его, пока у меня нет всех сделанных операторов набора.

4
ответ дан 4 December 2019 в 06:31
поделиться

Нет, для прозрачного преобразования (бросок), объект от одного типа до другого, базового реального класса объекта, который Вы имеете, должен наследоваться классу, к которому Вы пытаются бросить его, даже если они оба реализуют тот же интерфейс.

Думайте об этом, все два объекта должны иметь общего для реализации того же интерфейса, то же подмножество сигнатур методов. Они не могли бы (вероятно, не сделать), даже имеют те же свойства или поля данных.

3
ответ дан 4 December 2019 в 06:31
поделиться
   ISomeInterface sc = new SomeClass() as ISomeInterface;
   SomeOtherClass soc = new SomeOtherClass();
   foreach (PropertyInfo info in typeof(ISomeInterface)
                                     .GetProperties(BindingFlags.Instance
                                                     |BindingFlags.Public))
   {
       info.SetValue(soc,info.GetValue(sc,null),null);
   }
3
ответ дан 4 December 2019 в 06:31
поделиться
Другие вопросы по тегам:

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