скопируйте класс, C#

Мы используем функцию array_filter, чтобы узнать количество значений в массиве

$array=array('','','other','','other');
$filled_array=array_filter($array);// will return only filled values
 $count=count($filled_array);
echo $count;// returns array count
24
задан 23 June 2009 в 07:02
поделиться

8 ответов

Вы, вероятно, имеете в виду глубокую копию ( глубокая копия против мелкой копии )?

Вам либо нужно:

  1. реализовать (жесткий код) метод самостоятельно,
  2. попробуйте реализовать (или найти) реализацию, которая использует Reflection или Emit для динамического выполнения (объяснено здесь ),
  3. используйте сериализацию и десериализацию для создания глубокой копии, если объект помечен атрибутом [Serializable] .
public static T DeepCopy<T>(T other)
{
    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(ms, other);
        ms.Position = 0;
        return (T)formatter.Deserialize(ms);
    }
}

Чтобы получить неглубокую копию, вы можете использовать метод Object.MemberwiseClone () , но это защищенный метод, это означает, что вы можете использовать его только изнутри класса.

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

38
ответ дан 28 November 2019 в 22:17
поделиться

Не все классы имеют эту функциональность. Возможно, если класс есть, он предоставляет метод Clone . Чтобы помочь реализовать этот метод для ваших собственных классов, существует защищенный метод MemberwiseClone , определенный в System.Object , который создает мелкую копию текущего экземпляра (т.е. поля копируются; если они являются ссылочными типов, ссылка будет указывать на исходное местоположение).

20
ответ дан 28 November 2019 в 22:17
поделиться

Я думаю, что автор спрашивает о конструкторах копирования ...

Ответ - «да, но только если вы реализуете это самостоятельно», нет «автоматического» способа сделать это без некоторые тяжелые ключи (читается: Reflection):

class MyClass {
    private string _name;

    // standard constructor, so that we can make MyClass's without troubles
    public MyClass(string name) {_name = name}
    public MyClass(MyClass old) {
        _name = old._name;
        // etc...
    }
}

Еще одна вещь, на которую следует обратить внимание в этом отношении, - это интерфейс IClonable и предоставляемый им метод .Clone () . Также в реализации обоих этих методов может помочь защищенный метод .MemberwiseClone () , предоставленный классом Object .

4
ответ дан 28 November 2019 в 22:17
поделиться

Не любой простой способ, который всегда будет работать. Если ваш класс [Serializable] или реализует ISerializable , вы можете выполнить сериализацию в оба конца для создания идентичной копии. То же самое работает для [DataContract]

. Если вам нужна только неглубокая копия, вы можете попробовать Object.MemberwiseClone () . Однако это защищенный метод, и вы можете использовать его только внутри класса.

Если вам повезет, класс реализует ICloneable , и вы можете просто вызвать метод Clone () .

2
ответ дан 28 November 2019 в 22:17
поделиться

Одна из возможностей - клонировать его. Вы должны реализовать интерфейс ICloneable и метод Clone .

1
ответ дан 28 November 2019 в 22:17
поделиться

Вы имеете в виду конструктор копирования, как он существует в C ++?

Он не существует в C #. Что вы можете сделать, так это написать свой собственный (что утомительно) или написать метод 'Clone', который использует сериализацию для создания нового экземпляра, который имеет точно такие же значения, что и исходный класс.

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

1
ответ дан 28 November 2019 в 22:17
поделиться

Да и нет. Это та область, где вам нужно быть немного осторожным, потому что есть некоторые ловушки (и опять же, это не сложно).

Прежде всего, если вы немного покопаетесь в библиотеке базовых классов (BCL), вы может обнаружить интерфейс ICloneable . Не все типы реализуют этот интерфейс, но те, у которых есть метод Clone, который вернет новый экземпляр того же типа с (предположительно) теми же значениями.

Однако здесь кроется ловушка: интерфейс ICloneable недостаточно определяет ожидается ли глубокий или неглубокий клон, поэтому одни реализации делают одно, а другие - другое. По этой причине ICloneable используется нечасто, и его дальнейшее использование активно не приветствуется - дополнительные подробности см. В отличном Framework Design Guidelines .

Если углубиться в BCL, можно обнаружить, что System.Object имеет защищенный метод MemberwiseClone . Хотя вы не можете вызвать этот метод напрямую из другого типа, вы можете использовать этот метод для реализации клонирования в ваших собственных объектах.

Распространенный шаблон клонирования - определить защищенный конструктор класса, который вы хотите клонировать, и передать уже существующий экземпляр в качестве параметра. Примерно так:

public class MyClass()
{
    public MyClass() {}

    protected MyClass(MyClass other)
    {
        // Cloning code goes here...
    }

    public MyClass Clone()
    {
        return new MyClass(this);
    }
}

Однако это, очевидно, работает только в том случае, если вы управляете типом, который хотите клонировать.

Если вы хотите клонировать тип, который вы не можете изменить и который не предоставляет метод Clone, вам нужно будет написать код для явного копирования каждого фрагмента данных из старого экземпляра в новый.

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

Распространенный шаблон клонирования - определить защищенный конструктор класса, который вы хотите клонировать, и передать уже существующий экземпляр в качестве параметра. Примерно так:

public class MyClass()
{
    public MyClass() {}

    protected MyClass(MyClass other)
    {
        // Cloning code goes here...
    }

    public MyClass Clone()
    {
        return new MyClass(this);
    }
}

Однако это, очевидно, работает только в том случае, если вы управляете типом, который хотите клонировать.

Если вы хотите клонировать тип, который вы не можете изменить и который не предоставляет метод Clone, вам нужно будет написать код для явного копирования каждого фрагмента данных из старого экземпляра в новый.

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

Распространенный шаблон клонирования - определить защищенный конструктор класса, который вы хотите клонировать, и передать уже существующий экземпляр в качестве параметра. Примерно так:

public class MyClass()
{
    public MyClass() {}

    protected MyClass(MyClass other)
    {
        // Cloning code goes here...
    }

    public MyClass Clone()
    {
        return new MyClass(this);
    }
}

Однако это, очевидно, работает только в том случае, если вы управляете типом, который хотите клонировать.

Если вы хотите клонировать тип, который вы не можете изменить и который не предоставляет метод Clone, вам нужно будет написать код для явного копирования каждого фрагмента данных из старого экземпляра в новый.

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

public class MyClass()
{
    public MyClass() {}

    protected MyClass(MyClass other)
    {
        // Cloning code goes here...
    }

    public MyClass Clone()
    {
        return new MyClass(this);
    }
}

Однако это, очевидно, работает только в том случае, если вы управляете типом, который хотите клонировать.

Если вы хотите клонировать тип, который вы не можете изменить и который не предоставляет метод Clone, вам нужно будет написать код для явного копирования каждого фрагмента данных из старого экземпляра в новый.

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

public class MyClass()
{
    public MyClass() {}

    protected MyClass(MyClass other)
    {
        // Cloning code goes here...
    }

    public MyClass Clone()
    {
        return new MyClass(this);
    }
}

Однако это, очевидно, работает только в том случае, если вы управляете типом, который хотите клонировать.

Если вы хотите клонировать тип, который вы не можете изменить и который не предоставляет метод Clone, вам нужно будет написать код для явного копирования каждого фрагмента данных из старого экземпляра в новый.

5
ответ дан 28 November 2019 в 22:17
поделиться

Простой способ клонировать объект - записать его в поток и прочитать его снова:

public object Clone()
{
    object clonedObject = null;
    BinaryFormatter formatter = new BinaryFormatter();
    using (Stream stream = new MemoryStream())
    {
        formatter.Serialize(stream, this);
        stream.Seek(0, SeekOrigin.Begin);
        clonedObject = formatter.Deserialize(stream);
    }

    return clonedObject;
}

Но имейте в виду, что это может вызвать проблемы с так называемым агрегатным объектом.

1
ответ дан 28 November 2019 в 22:17
поделиться
Другие вопросы по тегам:

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