Копирование свойства интерфейса в С#

Я работаю с С# уже много лет, но просто сталкиваюсь с этой проблемой, которая меня бросает, и я действительно даже не знаю, как задать вопрос, поэтому на примере!

public interface IAddress
{
  string Address1 { get; set; }
  string Address2 { get; set; }
  string City { get; set; }
  ...
}

public class Home : IAddress
{
  // IAddress members
}

public class Work : IAddress
{
  // IAddress members
}

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

Спасибо!

Ответы

Ответ 1

Для этого нет ни одного лайнера.

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

У BTW COBOL есть выражение для этого: ПЕРЕМЕЩЕНИЕ КОРРЕСПОНДЕНА ДОМА ДЛЯ РАБОТЫ.

Ответ 2

Здесь один из способов сделать это, который не имеет ничего общего с интерфейсами:

public static class ExtensionMethods
{
    public static void CopyPropertiesTo<T>(this T source, T dest)
    {
        var plist = from prop in typeof(T).GetProperties() where prop.CanRead && prop.CanWrite select prop;

        foreach (PropertyInfo prop in plist)
        {
            prop.SetValue(dest, prop.GetValue(source, null), null);
        }
    }
}

class Foo
{
    public int Age { get; set; }
    public float Weight { get; set; }
    public string Name { get; set; }
    public override string ToString()
    {
        return string.Format("Name {0}, Age {1}, Weight {2}", Name, Age, Weight);
    }
}

static void Main(string[] args)
{
     Foo a = new Foo();
     a.Age = 10;
     a.Weight = 20.3f;
     a.Name = "Ralph";
     Foo b = new Foo();
     a.CopyPropertiesTo<Foo>(b);
     Console.WriteLine(b);
 }

В вашем случае, если вам нужен только один набор свойств интерфейса для копирования, вы можете сделать это:

((IAddress)home).CopyTo<IAddress>(b);

Ответ 3

Вы можете создать метод расширения:

public static void CopyAddress(this IAddress source, IAddress destination)
{
    if (source is null) throw new ArgumentNullException("source");
    if (destination is null) throw new ArgumentNullException("destination");

    //copy members:
    destination.Address1 = source.Address1;
    //...
}

Ответ 4

Jimmy Bogard AutoMapper очень полезен для такой операции отображения.

Ответ 5

Я не верю, что для этого есть готовое к языку решение (все свойства должны иметь геттеры и сеттеры).

Вы можете создать Address как абстрактный класс с помощью метода Copy (Address add).

В качестве альтернативы вы можете сделать Home и Work, чтобы иметь IAddress, и не расширять его. Затем копия будет немедленной.

Ответ 6

Вам нужно будет создать метод для этого

public void CopyFrom(IAddress source)
{
    this.Address1 = source.Address1;
    this.Address2 = source.Address2;
    this.City = source.city;
}

Ответ 7

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

например,

public WorkAddress(Iaddress address)
{
    Line1 = IAddress.Line1;
    ...
}

Для удобства использования используйте отражение, чтобы получить имена свойств.

НТН,

Dan

Ответ 8

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

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