C#通用方法避免代码重复

时间:2016-09-29 00:15:38

标签: c# .net generics

我正在使用三个具有通用接口的不同类。但是,界面不包括所有三个方法和属性。因此,我遇到了代码重复的情况,见下文:

if (party is Entity)
{
    var entity = party as Entity;

    txtName1.Text = entity.Name1;

    Address addr = entity.Addresses.FindPrimary();
    txtAddr1.Text = addr.Address1;
    txtCity.Text = addr.City;
    txtZip.Text = addr.Zip;
}
else if (party is CustomerAccount)
{
    var acct = party as CustomerAccount;

    txtName1.Text = acct.Name1;

    Address addr = acct.Addresses.FindPrimary();
    txtAddr1.Text = addr.Address1;
    txtCity.Text = addr.City;
    txtZip.Text = addr.Zip;
}
else if (party is CustomerQuote)
{
    var quote = party as CustomerQuote;

    txtName1.Text = quote.Name1;

    Address addr = quote.Addresses.FindPrimary();
    txtAddr1.Text = addr.Address1;
    txtCity.Text = addr.City;
    txtZip.Text = addr.Zip;
}

有没有办法创建一个通用的方法来处理这种情况。如下所示:

private void getAddressInfo<T>(T party)
{
    var sharedType = party as party.GetType();

    txtName1.Text = sharedType.Name1;

    Address addr = sharedType.Addresses.FindPrimary();
    txtAddr1.Text = addr.Address1;
    txtCity.Text = addr.City;
    txtZip.Text = addr.Zip;
}

3 个答案:

答案 0 :(得分:4)

Automapper就是为了这个目的而设计的。您可以在不同对象类型之间设置映射,它可以自动映射同名属性。这是一个simple example。这是NuGet

如果您不想使用第三方工具,可以使用this question中的一个答案。

当然,最好的选择是修改域类,使它们都为它们共有的元素实现接口(例如IAddress)......但我假设你问这个问题,因为在这种情况下,你无法做到这一点。

答案 1 :(得分:4)

public interface ICompanyAddress
{
    public string Name1 {get; set;}
    public Address Addresses {get; set;}

    //probably other similar stuff
}

public class Entity:ICompanyAddress
{
     //all properties which are needed from the interface
}

//all other classes with same properties should also inherit ICompanyAddress

您的类应该继承此接口。创建对象时,您将以这种方式创建它们:

ICompanyAddress entity = new Entity();
ICompanyAddress customerAcc= new CustomerAccount();

你可以这样称呼方法:

private void SetAddressInfo(ICompanyAddress addressObj)
{

    txtName1.Text = addressObj.Name1;

    Address addr = addressObj.Addresses.FindPrimary();
    txtAddr1.Text = addr.Address1;
    txtCity.Text = addr.City;
    txtZip.Text = addr.Zip;
}

在这里你如何调用方法:

ICompanyAddress customerAcc= new CustomerAccount();

SetAddressInfo(customerAcc);

答案 2 :(得分:4)

如果您不能将所有共享属性应用于公共接口,那么您可以查看鸭子类型(Using Type dynamic),其中属性和方法在运行时实现。

您可以访问公共接口的属性和方法,然后可以转换为动态类型并调用其他属性和方法。

例如,假设一个通用接口......

xpack.security.enabled: false

通用方法看起来像这样......

public interface ICommonInterface {
    string Name1 { get; }
}

并像这样使用

private void getAddressInfo<T>(T party) where T : ICommonInterface {
    //access common  properties
    txtName1.Text = party.Name1;

    //convert to dynamic to call other properties and methods.
    dynamic sharedType = party;

    Address addr = sharedType.Addresses.FindPrimary();
    if (addr != null) {
        txtAddr1.Text = addr.Address1;
        txtCity.Text = addr.City;
        txtZip.Text = addr.Zip;
    }
}

虽然这是一个快速的解决方法,但请注意,您不会遇到公共接口中未定义的方法和属性的编译时错误。但是,如果代码无效,则会在运行时捕获错误。但是,由于您可以控制代码,因此您应该事先确保所调用的属性和方法存在。