c# - 我可以忽略 C# 接口(interface)中的泛型类型吗?

标签 c# generics interface sieve.net

背景

我开始研究一个名为 Sieve.NET 的小型 OSS 库.

签名让某人定义一个 Sieve如下:

new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt);

这实际上返回一个 Sieve<ABusinessObject, int> ,但我已尽力确保用户不必过多关心该部分。

任务

我想找到一种方法在上面放置一个接口(interface),我根本不关心属性类型——只关心它始终是一致的。

所以基本上,我希望能够声明一个 ISieve<TFilterObjectType> ,并且能够让该接口(interface)定义如下内容:

ISieve<TFilterObjectType, TTypeIDontCareAbout> ForValue(TTypeIDontCareAbout);

我的目标是能够有一个由 ISieve<ABusinessObject> 组成的类而不是 ISieve<ABusinessObject, int> .

问题

  • 有没有一种方法可以让接口(interface)声明一个实际上是通配符的类型,并说“我不关心这是什么类型,只关心它是一致的吗?”

我的初步研究表明没有,但我希望被证明是错误的。

更新和澄清

我真正想弄清楚的是:

  • 我允许用户创建 EqualitySieve<ABusinessObject>().ForProperty(x=>x.AnInt) .
  • 这实际上返回一个 EqualitySieve<ABusinessObject, int>对用户来说,但由于它是一个流畅的界面,我让他们不必关心那部分。
  • 我想要EqualitySieve , LessThanSieve等来实现ISieve<ABusinessObject> .
  • 我想要ISieve<ABusinessObject执行契约(Contract),我可以允许某人调用ForValues()并期望它返回具有更新值的 ISieve。
  • 然而,在那个时候,EqualitySieve<ABusinessObject>实际上是一个 EqualitySieve<ABusinessObject, int> .但那时我并不特别关心属性类型。
  • 本质上,因为我正在抽象出 EqualitySieve<ABusinessObject, int>部分,我还想看看在通过接口(interface)引用对象时是否可以将其抽象掉。
  • 长期计划是我想要一个 SieveLocator,其中类可以实现 IFindableSieve<ABusinessObject>理想情况下会返回 ISieve<ABusinessObject> .那么我的目标就是能够为给定的对象找到那些筛子。
  • 所以我认为这可能是我设计的局限性,我必须找到其他解决方法。对此的任何建议或对我可能看不到的模式的引用也会有所帮助。

最佳答案

您可以将通用类型参数放在接口(interface)和接口(interface)的方法上。因此,以下示例将定义一个通用接口(interface),其中 F方法采用这些“我不关心这是什么类型,只关心它是一致的”参数之一。

interface I<T>
{
    //The generic type parameter U is independent of T.
    //Notice how F "forwards" the type U from input to output.
    Tuple<T, U> F<U>(U u);
}

考虑以下玩具类:

class C : I<char>
{
    public char Value { get; set; }
    public Tuple<char, U> F<U>(U u)
    {
        return Tuple.Create(Value, u);
    }
}

下面是一些示例用法:

I<char> instance = new C { Value = '!' };
Tuple<char, int> x = instance.F(5); // ('!', 5)
Tuple<char, string> y = instance.F("apple"); // ('!', "apple")

更新

  • I allow users to create an EqualitySieve<ABusinessObject>().ForProperty(x=>x.AnInt).
  • This actually returns an EqualitySieve<ABusinessObject, int> to the user, but since it's a fluent interface I remove them from having to care about that part.
  • I would like EqualitySieve, LessThanSieve, etc. to implement ISieve<ABusinessObject>.

使用我上面提到的想法,你可以做(​​我认为)你想做的事。

interface ISieve<T>
{
    //It's still not clear what you actually want in this interface...
}

static class Sieve
{
    public EqualitySieve<T> Equality<T>()
    {
        return new EqualitySieve<T>();
    }

    public LessThanSieve<T> LessThan<T>()
    {
        ...
    }
}    

class EqualitySieve<T> : ISieve<T>
{
    //Notice how the property type P is independent of T
    //and can be inferred here from the passed expression
    public EqualitySieve<T, P> ForProperty<P>(
        Expression<Func<T, P>> propertyExpression)
    {
        return new EqualitySieve<T, P>
        {
            PropertyExpression = propertyExpression
        };
    }
}

class EqualitySieve<T, P> : ISieve<T>
{
    public Expression<Func<T, P>> PropertyExpression { get; set; }
}

用法:

//Assuming MyObject.MyProperty is an int property
//s has type EqualitySieve<MyObject, int>
var s = Sieve.Equality<MyObject>().ForProperty(x => x.MyProperty);

关于c# - 我可以忽略 C# 接口(interface)中的泛型类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24024097/

相关文章:

c# - 如何将我的异常信息放入 IEnumerable<string>

C# Func<> 和泛型

java - 使用变量类名而不是大量的 if 子句?

java - 数据类型接口(interface)数组

c# - 从字符串中删除指定的标点符号

c# - 为什么 return 语句必须在 catch block 中的 throw 语句之前

c# - 如何在mvc中将复杂的键值参数从 View 传递到 Controller ?

Java Generics Hell - 传入这个但它想要类型 T

java - 为什么在 Java 中调用通用重写函数会产生 2 个堆栈帧

java - 在此接口(interface)定义中,尖括号是什么意思?