简体   繁体   中英

C#, WinForms and Extension Methods

The Question

Aside from all the obvious answers, what would cause extension methods to generate compiler errors like this one:

'DataType' does not contain a definition for 'YourExtensionMethodName'

I've got a real stumper here, and it's spelled out for you in detail below. I've exhausted all the possible causes I can think of.

Scenario

  • I have a couple of extension methods defined in various static classes in a DLL that is consumed by a WinForms application.
  • The extension method signatures do not conflict with the signatures of methods on the class I'm extending ( String , in this case).
  • Both the DLL and the WinForms application are written in C#.
  • Both the DLL and the WinForms application are configured to target .NET 3.5.
  • The consuming classes include a reference to the namespace that defines the extension method. Its spelling has been verified.
  • If I reference the extension class directly, the extension methods appear. For example, if I type StringExtensions. , Intellisense appears as normal, with all of my extension methods listed.
  • EDIT : The errors are occurring in the WinForms application, but only for some of the extension methods, not all of them.

The Code (Or an Excerpt Thereof)

(Yep, this is the offending code)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Roswell.Framework
{
    public static class StringBuilderExtensions
    {
        public static string ToSentenceCase(this string value)
        {
            return value.Substring(0, 1).ToUpper() + value.Substring(1).ToLower();
        }

        public static string ToTitleCase(this string value)
        {
            string[] parts = value.Split(new string[] {" "}, StringSplitOptions.None);
            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            foreach (string part in parts)
            {

                builder.Append(part.ToSentenceCase());
                builder.Append(" ");
            }
            return builder.ToString();
        }

    }
}

And this is the code that consumes it:

using Roswell.Framework;

namespace Roswell.Windows.Command
{
    /// <summary>
    /// Views the SQL for an object in the database window.
    /// </summary>
    internal class ViewObjectDdlCommand
        : MainWindowCommand
    {

        public override void Execute()
        {
           // ...

           OpenCodeWindow(
               string.Format("{0} - {1} - {2}", 
                             dsn.Name, 
                             objectName, 
                             info.ToTitleCase()),
                schemaItemType,
                objectName);
         }
    }
}

From your code snippet, I can see you're calling ToTitleCase on something called info . But I can't see the type of that variable, which is the thing that will determine what is happening here.

Obviously it needs to be a string (if string was not a sealed class it could be something derived from string, but that's impossible for a sealed class).

So the only thing that makes sense (aside from a very unlikely compiler error) is that info is not a string.

The error suggests the answer:

'DataType' does not contain a definition for 'YourExtensionMethodName'

In this case, my guess is that "info" ( ViewObjectDdlCommand.info ) is not a string, but rather DataType. Try changing it to:

OpenCodeWindow(
    string.Format("{0} - {1} - {2}", 
        dsn.Name, 
        objectName, 
        info.ToString().ToTitleCase()),
        schemaItemType,
        objectName);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM