有没有办法使用一个好友的'这个类/接口的名称?

时间:2018-05-18 05:51:50

标签: c# generics interface user-friendly

基本上我只是觉得类型名称在我的项目中传递时很难看。我知道你不能使用实现接口的接口,因为它是一个刚刚实现原始接口的新接口,对吧?

public class GenericFactory<T, TTypeEnum> : IGenericFactory<T, TTypeEnum>
{
    private readonly IIndex<TTypeEnum, Func<CCompParms, T>> _factory;

    public GenericFactory(IIndex<TTypeEnum, Func<CCompParms, T>> factory)
    {
        _factory = factory;
    }

    public T Create(TTypeEnum serviceType, CCompParms comp)
    {
        return _factory[serviceType](comp);
    }
}

public interface IGenericFactory<T, TTypeEnum>
{
    T Create(TTypeEnum serviceType, CCompParms comp);
}

我试过了:

public interface FriendlyName : IGenericFactory<T, TTypeEnum>
{
}

但是当我尝试做以下事情时,无论我如何施展它都无法施展。

IGenericFactory<T, TTypeEnum> inter = GetTheInterface();
FriendlyName fn = (inter as FriendlyName);

有没有办法让类型名称友好?

1 个答案:

答案 0 :(得分:1)

首先,对于“友好名称”的任何一般解决方案仍然必须使用两种泛型类型进行参数化,所以我不认为这是你正在寻找的,因为它不会真正为你节省任何打字

假设您希望FriendlyName已经绑定了类型,那么 我认为您可以使用Implicit ConversionsDecorator模式找到可行的解决方案。

警告!!!我只是在浏览器中键入了这个(没有IDE或编译器)而且我的C#非常生疏,所以这可能需要调整

public interface FooFactory : IGenericFactory<Foo, FooEnum> {

    IGenericFactory<Foo, FooEnum> Wrapped { get; }

    // The "magic" - Note that magic always makes your code harder to understand...

    public static implicit operator FooFactory(IGenericFactory<Foo, FooEnum> wrapped) {
        // I think this can be placed here. If C# won't let you add this
        // implicit operator here, then you can easily implement this factory
        // method as an extension on IGenericFactory<Foo, FooEnum>
        return new FooFactoryWrapper(wrapped);
    }

    public static implicit operator IGenericFactory<Foo, FooEnum>(FooFactory wrapper) {
        return wrapper.Wrapped;
    }

    // I'm pretty sure we can hide this implementation here in the interface,
    // but again, my C# is pretty rusty, so you may have to move this
    // and/or change the visibility
    private class FooFactoryWrapper : FooFactory {

        public IGenericFactory<Foo, FooEnum> Wrapped { get; private set; }

        public FooFactoryWrapper(IGenericFactory<Foo, FooEnum> wrapped) {
            this.wrapped = wrapped;
        }

        // Since the "friendly type" is still an instance of the base type,
        // you'll still have to fully implement that interface. Just delegate
        // all calls to your wrapped type (most useless Decorator ever)

        public Foo Make() { return Wrapped.Make(); } // sample method in IGenericFactory<>
    }
}

现在,你能够像这样使用它:

IGenericFactory<Foo, FooEnum> inter = GetTheInterface();
FooFactory fn = inter; // implicit conversion to wrapper type

DoWork(fn); // use the "friendly name" like it were it's wrapped type
            // implicit conversion back to wrapped type

public void DoWork(IGenericFactory<Foo, FooEnum> fooFactory) {
    ...
}

所有这一切,我都不会经历这种努力。每当我创建这样的“友好名称”类型时,我就会将它们作为我的“模型”的一部分,并将它们视为正确的类型,这意味着我直接在方法签名和构造函数中请求它们。

这样的事情:

public interface BarFactory : IGenericFactory<Bar, BarEnum> { }

// Asking for a BarFactory and not a IGenericFactory<Bar, BarEnum>
public void DoWork(BarFactory barFactory) { ... }

打字少得多,不需要魔术。