c#中的接口属性副本

时间:2009-08-13 15:55:01

标签: c# interface

我已经和C#合作多年了,但是刚遇到这个问题让我感到困惑,我甚至不知道如何提出这个问题,所以,举个例子!

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属性的值从一个类复制到另一个类。这可能是一个简单的单行语句还是我仍然需要对每个语句进行属性到属性的分配?我真的很惊讶这个看似简单的东西让我感到难过...如果它不可能以简洁的方式,有没有人有任何捷径他们用来做这类事情?

谢谢!

8 个答案:

答案 0 :(得分:19)

这是一种与接口无关的方法:

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).CopyPropertiesTo<IAddress>(b);

答案 1 :(得分:12)

您可以构建扩展方法:

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;
    //...
}

答案 2 :(得分:4)

Jimmy Bogard的AutoMapper对于那种映射操作非常有用。

答案 3 :(得分:3)

这没有任何一个班轮。

如果你做了很多,你可以研究某种形式的代码生成,也许使用T4模板和反射。

BTW COBOL对此有一个声明:移动相应的家庭工作。

答案 4 :(得分:2)

我不相信有一个语言就绪解决方案(所有属性都需要有getter和setter)。

您可以使用复制(地址添加)方法将地址创建为抽象类。

或者,您可以将Home and Work设为拥有IAddress,而不是扩展IAddress。然后立即复制。

答案 5 :(得分:1)

您需要创建一个方法来执行此操作

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

答案 6 :(得分:0)

你可以在每个类上使用一个构造函数来获取IAddress,并实现了在其中填充的成员。

例如

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

为了可维护性,请使用反射来获取属性名称。

HTH,

答案 7 :(得分:0)

如果您将家庭和工作地址的公共部分封装在一个单独的课程中,它可能会让您的生活更轻松。然后,您可以简单地复制该属性。这对我来说似乎是更好的设计。

或者,您可以将具有反射和属性的解决方案混合在一起,其中一个对象中的属性值被复制到另一个对象中的匹配(和标记)属性。当然,这也不是一个单线解决方案,但如果你拥有大量属性,它可能比其他解决方案更快,更易于维护。