通过使用泛型避免在以下代码中进行强制转换

时间:2016-09-23 00:02:21

标签: c# oop generics

我是仿制药的新手,只是想知道是否可以使用更好的OO方法避免在以下代码中进行转换。

public class CollectorFactory
{
    public static MyCollector Create(ICredential credential)
    {
        return new MyCollector(credential);
    }
}

public class MyCollector {

    public MyCredential Credential { get; set; }

    public MyCollector(ICredential credential)
    {
        this.Credential = (MyCredential)credential;
    }

    public void Show()
    {
        Console.WriteLine(this.Credential.Username);
        Console.WriteLine(this.Credential.AuthToken);
    }
}

public class MyCredential : ICredential
{
    public string Username{ get; set;  }

    public string AuthToken { get; set; }
}

public interface ICredential
{

}

有没有办法在MyCollector'构造函数中保存ICredential到MyCredential的转换?我没有选择将Username和AuthToken放在ICredential中,因为它由两个具有不同属性集的不同凭证实现。 CollectorFactory将来会返回不同的MyCollector实例,并且都需要具有不同的凭据。

任何帮助都会非常感激。

3 个答案:

答案 0 :(得分:1)

我认为,如果您正在实施不同的凭据并尝试将其用于ICredential,我认为不可能。

答案 1 :(得分:0)

以下是使用泛型的方法。请在代码中阅读我的评论。

public class CollectorFactory<T>
{
    public T Create(ICredential credential)
    {
        return (T)Activator.CreateInstance(typeof(T), credential);
    }
}

public class MyCollector : BaseCollector
{
    public dynamic Credential { get; private set; }

    public MyCollector(ICredential credential)
        : base(credential)
    {
        this.Credential = credential;
    }

    // Having this method here limits your ability to make it more generic. 
    // Consider moving this to MyCredential since it refers to specific properties in MyCredential. 
    // If that is not what you want, then you must do a type check before calling methods/ accessing props in Credentials.
    public void Show()
    {
        Console.WriteLine(this.Credential.Username);
        Console.WriteLine(this.Credential.AuthToken);
    }
}

public class MyCredential : ICredential
{
    public string Username { get; set; }

    public string AuthToken { get; set; }
}

public abstract class BaseCollector : ICredentialCollector
{
    protected BaseCollector(ICredential credential)
    {
        if (credential == null)
        {
            throw new ArgumentNullException(nameof(credential));
        }
    }
}

public interface ICredentialCollector
{
}

public interface ICredential
{
}

// test implementation
public class TestClass
{
    public void AuthFactoryTest()
    {
        // test auth instance
        MyCredential auth = new MyCredential() {AuthToken = "asfgasdgdfg", Username = "xuser"};

        // Create test factory
        var fact = new CollectorFactory<MyCollector>(); 
        var myCollector = fact.Create(auth);

        // Do what you need to do to collector object
        myCollector.Show();
    }
}

答案 2 :(得分:-1)

在这种情况下,泛型不是解决方案。这里的问题是您的工厂正在返回特定类型(MyCollector)。围绕这个的解决方案如下:

public class CollectorFactory
{
    public static ICollector Create(MyCredential credential)
    {
        return new MyCollector(credential);
    }
    public static ICollector Create(OtherCredential credential)
    {
        return new OtherCollector(credential);
    }
}

public interface ICollector
{
    void Show();
}

public class MyCollector : ICollector 
{

    public MyCredential Credential { get; set; }

    public MyCollector(MyCredential credential)
    {
        this.Credential = credential;
    }

    public void Show()
    {
        Console.WriteLine(this.Credential.Username);
        Console.WriteLine(this.Credential.AuthToken);
    }
}

public class MyCredential : ICredential
{
    public string Username{ get; set;  }

    public string AuthToken { get; set; }
}

public interface ICredential
{

}

以上几乎是工厂设计模式的典型例子。

您可以在工厂中进行类型检查,而不是重载:

public class CollectorFactory
{
    public static ICollector Create(ICredential credential)
    {
        if(credential.GetType() == typeof(MyCredential))
            return new MyCollector((MyCredential) credential);
        if(credential.GetType() == typeof(OtherCredential ))
            return new OtherCollector((OtherCredential ) credential);
    }
}