结构体上的扩展方法

发布于 2024-10-11 06:14:53 字数 21 浏览 2 评论 0原文

您可以向结构添加扩展方法吗?

Can you add extension methods to a struct?

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

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

发布评论

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

评论(4

彼岸花ソ最美的依靠 2024-10-18 06:14:53

是的,您可以在结构上添加扩展方法。根据扩展方法的定义,您可以轻松实现它。下面是 int 扩展方法的示例

namespace ExtensionMethods
{
    public static class IntExtensions
     {
        public static bool IsGreaterEqualThan(this int i, int value)
        {
            return i >= value;
        }
    }
}

Yes, you can add extension methods on structs. As per the definition of extension method, you can easily achieve it. Below is example of extension method on int

namespace ExtensionMethods
{
    public static class IntExtensions
     {
        public static bool IsGreaterEqualThan(this int i, int value)
        {
            return i >= value;
        }
    }
}
下壹個目標 2024-10-18 06:14:53

可以向结构添加扩展方法,但有一个重要的警告。普通的结构体方法接受 this 作为 ref 参数,但 C# 不允许定义这样做的扩展方法。虽然改变 this 的结构方法可能有些危险(因为编译器将允许在只读结构上调用结构方法,但按值传递 this),但它们可以如果人们小心地确保它们只在适当的上下文中使用,有时也会很有用。

顺便说一句,vb.net 确实允许扩展方法接受 this 作为 ByRef 参数,无论它是类、结构还是未知类别的泛型。在某些接口可能由结构实现的情况下,这可能会很有帮助。例如,如果尝试在 List.Enumerator 类型的变量上调用采用 IEnumerator类型的 this 参数的扩展方法,则该方法将被调用。,或者通过值获取约束为 IEnumerator 的泛型的 this 参数,并且如果该方法尝试推进枚举器,则任何推进都将是当方法返回时撤消。然而,通过引用接受受约束泛型的扩展方法(可能在 vb.net 中)将按其应有的方式运行。

It is possible to add extension methods to structures, but there is an important caveat. Normal struct methods methods accept this as a ref parameter, but C# will not allow the definition of extension methods which do so. While struct methods which mutate this can be somewhat dangerous (since the compiler will allow struct methods to be invoked on read-only structures, but pass this by value), they can also at times be useful if one is careful to ensure that they are only used in appropriate contexts.

Incidentally, vb.net does allow extension methods to accept this as a ByRef parameter, whether it is a class, struct, or an unknown-category generic. This can be helpful in some cases where interfaces may be implemented by structures. For example, if one attempts to invoke on a variable of type List<string>.Enumerator an extension method which takes a this parameter of type IEnumerator<string>, or takes by value a this parameter of a generic constrained to IEnumerator<string>, and if the method tries to advance the enumerator, any advancement will be undone when the method returns. An extension method which takes a constrained generic by reference, however, (possible in vb.net) will behave as it should.

在梵高的星空下 2024-10-18 06:14:53

对于未来的 Google 员工(和 Bingers),这里有一些扩展结构的代码。此示例将值转换为 double 类型。

public static class ExtensionMethods {

   public static double ToDouble<T>(this T value) where T : struct {
      return Convert.ToDouble(value);
   }
}

之后,您可以像使用 ToString() 一样使用 ToDouble()。请注意溢出等转换项。

For future Googlers (and Bingers), here's some code to extend a struct. This example turns the value into a double type.

public static class ExtensionMethods {

   public static double ToDouble<T>(this T value) where T : struct {
      return Convert.ToDouble(value);
   }
}

After this you can use ToDouble() like you use ToString(). Be careful on conversion items like overflows.

↙温凉少女 2024-10-18 06:14:53

是的,您可以在结构/值类型上定义扩展方法。但是,它们的行为与引用类型的扩展方法不同。

例如,以下 C# 代码中的 GetA() 扩展方法接收结构体的副本,而不是对该结构体的引用。这意味着结构体上的 C# 扩展方法无法修改原始结构体内容。

public static class TestStructExtensionMethods {
    public struct FooStruct {
        public int a;
    }
    public static int GetA(this FooStruct st) {
        return st.a;
    }
}

为了修改结构体内容,需要将结构体参数声明为“ref”。但是,C# 中不允许使用“this ref”。我们能做的最好的就是静态非扩展方法,例如:

// this works, but is inefficient, because it copies the whole FooStruct
// just to return a
public static int GetA(ref FooStruct st) {
    return st.a;
}

在 VB.NET 中,您可以将其创建为 ByRef 结构扩展方法,因此它可以修改原始结构:

' This is efficient, because it is handed a reference to the struct
<Extension()> _ 
Public Sub GetA(ByRef [me] As FooStruct) As Integer
    Return [me].a
End Sub

' It is possible to change the struct fields, because we have a ref
<Extension()> _ 
Public Sub SetA(ByRef [me] As FooStruct, newval As Integer) 
    [me].a = newval
End Sub

Yes, you can define an extension method on a struct/value type. However, they do not have the same behavior as extension methods on reference types.

For example, the GetA() extension method in the following C# code receives a copy of the struct, not a reference to the struct. This means that a C# extension method on a struct can't modify the original struct contents.

public static class TestStructExtensionMethods {
    public struct FooStruct {
        public int a;
    }
    public static int GetA(this FooStruct st) {
        return st.a;
    }
}

In order to modify the struct contents, the struct paramater needs to be declared as "ref". However, "this ref" is not allowed in C#. The best we can do is a static non-extension method like:

// this works, but is inefficient, because it copies the whole FooStruct
// just to return a
public static int GetA(ref FooStruct st) {
    return st.a;
}

In VB.NET, you can create this as a ByRef struct extension method, so it could modify the original struct:

' This is efficient, because it is handed a reference to the struct
<Extension()> _ 
Public Sub GetA(ByRef [me] As FooStruct) As Integer
    Return [me].a
End Sub

' It is possible to change the struct fields, because we have a ref
<Extension()> _ 
Public Sub SetA(ByRef [me] As FooStruct, newval As Integer) 
    [me].a = newval
End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文