C# 中泛型类型的命名空间范围别名

发布于 2024-08-27 22:53:44 字数 1535 浏览 8 评论 0 原文

让我们看一个下面的例子:

public class X { }
public class Y { }
public class Z { }

public delegate IDictionary<Y, IList<Z>> Bar(IList<X> x, int i);

public interface IFoo
{
    // ...
    Bar Bar { get; }
}

public class Foo : IFoo
{
    // ...
    public Bar Bar
    {
        get
        {
            return null; //...
        }
    }
}

void Main()
{
    IFoo foo; //= ...
    IEnumerable<IList<X>> source; //= ...
    var results = source.Select(foo.Bar); // <- compile error here
}

编译器说:

方法的类型参数 'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)' 不能 从使用情况可以推断。尝试 指定类型参数 明确地。

这是因为,它无法将 Bar 转换为 Func, int, IDictionary>>

如果我可以在 C# 中为泛型类型创建类型命名空间范围的类型别名,那就太好了。然后我不会将 Bar 定义为委托,而是将其定义为 Func, int, IDictionary> 的命名空间范围别名;>

public alias Bar = Func<IList<X>, int, IDictionary<Y, IList<Z>>>;

然后,我还可以为例如 IDictionary> 定义名称空间范围的别名。

如果使用得当:),它将使代码更具可读性。现在,我必须内联泛型类型,而真正的代码可读性不好:(

你有没有发现同样的麻烦:)?有什么充分的理由为什么它不在 C# 3.0 中吗?或者没有充分的理由,只是金钱和/或时间的问题?

编辑:我知道我可以使用 using,但它不是命名空间范围的 - 对于我的情况来说不太方便。

EDIT2:请参阅 Joren 的评论,他建议结构类型也可以解决问题。

Let's have a following example:

public class X { }
public class Y { }
public class Z { }

public delegate IDictionary<Y, IList<Z>> Bar(IList<X> x, int i);

public interface IFoo
{
    // ...
    Bar Bar { get; }
}

public class Foo : IFoo
{
    // ...
    public Bar Bar
    {
        get
        {
            return null; //...
        }
    }
}

void Main()
{
    IFoo foo; //= ...
    IEnumerable<IList<X>> source; //= ...
    var results = source.Select(foo.Bar); // <- compile error here
}

The compiler says:

The type arguments for method
'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable,
System.Func)' cannot
be inferred from the usage. Try
specifying the type arguments
explicitly.

It's because, it cannot convert Bar to Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

It would be great if I could create type namespace scoped type aliases for generic types in C#. Then I would define Bar not as a delegate, but rather I would define it as an namespace scoped alias for Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

public alias Bar = Func<IList<X>, int, IDictionary<Y, IList<Z>>>;

I could then also define namespace scoped alias for e.g. IDictionary<Y, IList<Z>>.

And if used appropriately:), it will make the code more readable. Now, I have to inline the generic types and the real code is not well readable:(

Have you find the same trouble:)? Is there any good reason why it is not in C# 3.0? Or there is no good reason, it's just matter of money and/or time?

EDIT: I know that I can use using, but it is not namespace scoped - not so convenient for my case.

EDIT2: See comment by Joren where he suggests that structural typing might also solve the problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

香草可樂 2024-09-03 22:53:44

你运气不好; using 指令仅影响其当前文件。没有命名空间范围的类型别名机制。

这是一个相当频繁请求的功能,这是它的要点。但它也是一个“很高兴拥有”的便利功能,而不是真正为语言增加大量表征能力的功能,这是它的缺点。这样做固然很好,但它在优先级列表中并不是很高。

You're out of luck; the using directive affects only its current file. There is no namespace-wide type aliasing mechanism.

This is a fairly frequently requested feature, which is points for it. But it is also a "nice to have" convenience feature as opposed to one that really adds lots of representational power to the language, which is points against it. It would be nice to do, but it's not really high on the priority list.

痞味浪人 2024-09-03 22:53:44

如果您这样做...

var results = source.Select((x, i) => foo.Bar(x, i));

它可以为您找出类型,而无需显式指定它们。

(诚然,这更多的是一种解决方法,而不是解决方案)

If you do ...

var results = source.Select((x, i) => foo.Bar(x, i));

it can figure out the types for you without having to specify them explicitly.

(Admittedly this is more of a work-around than a solution)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文