"Private" visibility modifier - how to handle differences when converting C# to VB? - c#

The Background
I have converted the C# code below (found in TreeViewAdv file TreeColumn.cs) into VB.net code using the converter found at DeveloperFusion.com.
C#
using System;
//...(other using calls)
namespace Aga.Controls.Tree
{
[TypeConverter(typeof(TreeColumn.TreeColumnConverter)), DesignTimeVisible(false), ToolboxItem(false)]
public class TreeColumn : Component
{
private class TreeColumnConverter : ComponentConverter
{
public TreeColumnConverter()
: base(typeof(TreeColumn))
{
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return false;
}
}
}
//…Some, I believe, unrelated code
}
VB
Imports System.Collections.Generic
‘...(other Imports calls)
Namespace Aga.Controls.Tree
<TypeConverter(GetType(TreeColumn.TreeColumnConverter)), DesignTimeVisible(False), ToolboxItem(False)> _
Public Class TreeColumn
Inherits Component
Private Class TreeColumnConverter
Inherits ComponentConverter
Public Sub New()
MyBase.New(GetType(TreeColumn))
End Sub
Public Overrides Function GetPropertiesSupported(ByVal context As ITypeDescriptorContext) As Boolean
Return False
End Function
End Class
‘...some, I believe, unrelated code
End Class
The Problem
Access to TreeColumn.TreeColumnConverter in this line of the C# code is fine.
[TypeConverter(typeof(TreeColumn.TreeColumnConverter)), DesignTimeVisible(false), ToolboxItem(false)]
However, VB.Net does not allow access to that member in the converted line:
The error description reads: Aga.Controls.Tree.TreeColumn.TreeColumnConverter' is not accessible in this context because it is 'Private'. However, in both cases TreeColumn.TreeColumnConverter is declared Private.
The Question(s)
1.) The Why. As this is a learning project for me, I would like to know WHY the scopes are acting differently among the two languages. This is the more important question among the 2 of them.
2.) The How. What is the best way(s) to change the VB code to allow access of TreeColumnConverter to the identified line of code without opening up the scope to the point that it potentially creates naming confusions elsewhere? I COULD just declare it Public, but I imagine there is a more correct approach to this.
Things To Keep In Mind When Answering
1.) I know that in VB.net Private members are not available external to the object in which they were declared. So telling me this will not be helpful and in my mind is not an answer.

To me, it looks like that the different compilers use different philosophies when dealing with nested private types. C# says its OK to access it from an attribute on the higher level type, VB.NET says it's not. Maybe those philosophies weren't even intentional.
Anyway, to fix it in VB.NET you could use the TypeConverterAttribute constructor that uses a string instead of a Type, and put the fully-qualified nested type name as a string:
<TypeConverter("Aga.Controls.Tree.TreeColumn.TreeColumnConverter"), DesignTimeVisible(False), ToolboxItem(False)> _
Public Class TreeColumn
...

Ah, I believe I see your problem.
It's the namespaces.
VB.NET Chains the Namespaces.
Namespace Aga.Controls.Tree in vb.net would actually be your project's default namespace concatenated with the namespace declared in the file.
It would actually be Aga.Controls.Tree.Aga.Controls.Tree so it likely just can't get to the scope it needs to be because it's pointing to the wrong namespace.
C#, you fully qualify namespaces... DevFusion's converter (same as the one used in SharpDevelop IDE) doesn't know this.

Related

Use Internal Class in C# Harmony Patch

I'm pretty new to c#, and I'm using Harmony patches to make a mod for a video game. The method I'm trying to patch is a private method which takes an internal class instance as a parameter. I've been able to use reflection to handle private methods in a few other patches, but when I try to add the internal parameter, I get a build error saying the class is inaccessible due to it's protection level.
I was trying to use the solution from this question, but I think I'm having some scope issues. Right now, I have something like
using System;
...
using System.Reflection;
using HarmonyLib;
using namespacesFromGame; // Including namespace where the internal is declared
...
namespace MyMod
{
[HarmonyPatch(typeof(GameClass))]
class MyPatch
{
Type MyInternal = typeof(GameClass).Assembly.GetType("GameInternal");
public static bool MethodPatch(GameClass__instance,..., MyInternal myInternal, ...)
{
...
}
}
}
When I try to do this, it tells me The type or namespace name 'MyInternal' cannot be found.
Where should I be putting my MyInternal declaration so it can be used as a parameter to MethodPatch, and so I will also be able to use the myInternal instance in the patch?
In C# you cannot declare the type of a property with another variable.
I see two solutions to this problem.
You can either do this :
using System;
...
using HarmonyLib;
using namespacesFromGame; // Including namespace where the internal is
namespace MyMod
{
[HarmonyPatch(typeof(GameClass))]
class MyPatch
{
public static bool MethodPatch(GameClass __instance,..., object myInternal, ...)
{
...
// do reflexion to access the method, the field and prop the object
}
}
}
This should work; but if you are new to C# the reflection may not necessarily be the easiest thing to do and it can quickly make your code unreadable.
Or do this :
You can publicise (make public) the dll you want to use. If you do this, you will have access to all classes, methods and ect... By doing this you will only have to use the desired type. But, you will have to compile your code in unstable.
For publicise, i found two github repo :
https://github.com/rwmt/Publicise
https://github.com/iRebbok/APublicizer
(you can also create your own but I think that to start it would be better to take one already made)
It will require republishing the assembly each time there is an update if your mod is outdated.
I also create modes on unity games. This is the solution I use and some FrameWork for modding uses to.
I don't know if there are performance impacts of using unstable code and calling private methods.
I advise you this solution, you would get cleaner code and you will have access to code more easily. But that is my personal opinion.

Attempt to Add Instance of Class Fails

I'm trying to work with a C# USB HID library (Mike O'Brien's open-source HIDLibrary) from my VB.NET application. I was able to make calls to methods in one of the classes easily. However, another method I'd like to call into in a different class isn't working. I can't access it directly by invoking the namespace and class name like I did for the other class, as VS complains "that a reference to a non-shared member requires an object reference". The class is public, so I think I *should" be able to call into it, but OK, so I try to add an object reference in my app, and it complains "Overload resolution failed because no "New" is accessible". The two classes (one of which "works", the other of which doesn't) appear to be set up virtually identically: they're both declared public, as are both of the methods I'm trying to call into.
I'm still a bit new to C#, and OOP in general, so pardon the newb question.
The full classes are pretty big, so I'm going to attempt to only include the "relevant" parts, but if I'm leaving something out, please let me know.
How the class I'd like to access is defined:
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace HidLibrary
{
public class HidDevice : IHidDevice
{ ...
And the method itself I'm attempting to call:
public bool ReadFeatureData(out byte[] data, byte reportId = 0)
The way I've set up my VB.NET app to call into this dll:
Imports HidLibrary
Public Class DeviceIDTest
Dim HIDDeviceObj As New HidLibrary.HidDevice
And finally my attempt at a method call:
If HidDeviceObj.ReadFeatureData(InBuff, reportID) Then
Return InBuff
Else
Return False
End If
The constructor for HidDevice is internal, so it can only be called from other classes in the HidLibrary assembly, which is why you get the "Overload resolution failed because no "New" is accessible" error. Since the class is public, that probably implies that there is some other way to create instances. I have never used this library, but from a quick glance it looks like maybe you are supposed to use one of the static methods on HidDevices, i.e. GetDevice or one of the Enumerate methods, to access instances of HidDevice.
For example (completely untested code!):
Dim data() As Byte
For Each device In HidDevices.Enumerate()
If device.ReadFeatureData(data) Then
' Do something with data?
End If
Next

How does C# pick when two class names collide

I have the following two files:
IGlobalApiProvider.cs
using System.Collections.Generic;
using Vert.Slack;
namespace Vert.Interfaces
{
public interface IGlobalApiProvider
{
List<Im> ImList();
}
}
And the corresponding implementation: SlackApi.cs
using System.Collections.Generic;
using Vert.Interfaces;
namespace Vert.Slack
{
public class SlackApi : IGlobalApiProvider
{
public List<Im> ImList()
{
...
}
}
}
Now, Intellisense is telling me that when I use IM in IGlobalApiProvider it's resolving to Im, which is defined in a file named RtmStart.cs which has no namespace declaration. When I use IM in SlackApi.cs, it's resolving to Vert.Slack.Im which is defined in the Vert.Slack namespace in a file named Im.cs. The weird behavior alerted me to the redundant definition, so I removed it and things are working fine.
However, I'm confused about why Visual Studio behaved differently in these two ways. I can tell something was scanning for the class names in a different pattern in the two situations. I can also tell that being used in the same namespace vs being used in a class that uses the namespace seems to be the trigger. What I don't know is what mechanism controls the logic behind this behavior.
Can anyone shed light on this?
Everything you see is contained in Vert.dll, which consists of one project, Vert.csproj
Link to the four files mentioned in this post as they existed at the time of writing.
This has to do with the difference between the global and Vert.Slack namespaces.
The compiler looks for the most explicit namespace with the proper class defined.
In this example, when the compiler looks for the definition of Im in IGlobalInterfaceProvider.cs, there is no namespace defined (or used) in this file that contains the class, but Im is also defined in this file - which is declared in the global namespace.
When the compiler looks for the definition of Im in SlackApi.cs, Im is found in the explicit Vert.Slack namespace, and utilizes that class.
The answer here is a similar topic and may provide more insight.
This may be related to the fact that your namespaces are in the wrong place ;-)
http://www.stylecop.com/docs/SA1200.html
This answer here gives a good explanation: Should 'using' statements be inside or outside the namespace?

What hack can I use to define a C# property with same name as class?

I'm using C# to make a .Net class library (a DLL) that will be distributed widely. I have an abstract class called Value, and I want it to have an abstract double property that is also called Value i.e.
public abstract class Value {
// Only accessible by subclasses within the project.
internal Value() {}
public abstract double Value {
get;
}
}
But the C# compiler won't allow this - I get the message "member names cannot be the same as their enclosing type", as discussed here.
I understand that the easiest thing to do would be to change the name of the property or the name of the class... But really I want the names to be like that, and I'm quite happy to implement an ugly hack to get it that way. So long as it works properly from external code that uses this DLL.
Unlike C#, VB.Net will allow me to define a property with the same name as the class, so I'm currently investigating merging my C# project with a VB project that defines the Value class (and its Value property) to make one DLL. This doesn't seem to be quite as straightforward as I was hoping.
Another option would be to re-write the whole project in VB... Not very appealing, but I'll consider it if necessary. I prefer C# over VB.Net but my priority is to get the built DLL the way I want it.
I'm wondering what other alternatives there might be. Any ideas for a good way to hack this?
EDIT: From the comments below it's clear that quite a number of people don't think much of the name "Value" for a class... Could anyone explain why it's so bad? I know it's not very descriptive, but I think it fits well in the context of my project. Is it because it's a keyword in C# that's used in property setters?
You cannot do that directly. You could, however, consider:
impelenting an interface with a Value member, and using explicit interface implementation (callers would have the use the interface, though)
renaming it in the class, and using an extension method to expose a Value() method, so obj.Value() works
rename it in the class, but expose it as Value in the subclasses
Ugly hack:
public abstract class ValueBase {
public abstract double Value { get; }
internal ValueBase() {}
}
public abstract class Value : ValueBase {
internal Value() {}
}
public sealed class ValueReal : Value {
public override double Value { get { return 123; } }
}
If your class is representative of a double (except for some additional metadata), you could opt for a conversion operator:
public abstract class Value
{
protected abstract double GetValue();
public static explicit operator double (Value value)
{
return value.GetValue();
}
}
Then your client code could access the metadata or cast an instance of type Value to a double. Depending on the metadata and usage, you might make the conversion implicit so you don't have to do an explicit cast, and you might define a conversion from double to Value.
There is a similar approach used by the System.Xml.Linq assembly where, for example, XElement can be cast to any primitive type as a means of accessing its "value".
As other people have said, this is not possible in C#.
Other people have criticised the name Value as a class, and while I agree it's likely too generic, I can see situations where it may make sense.
Bearing that in mind, if Value is an abstract class, perhaps ValueBase might be a decent, conformant, name? Much of the .Net framework (particularly WPF) uses XxxBase.
Another option to consider is prefixing the class name with the name of your project, as in FooValue.
Value is a terrible name for a class. It's extremely vague, so it does nothing to describe what a Value represents, and it clashes with the reserved word 'value'. You will find yourself using value = Value.Value, wondering why your code makes no sense, and eventually trying to fix a hideous bug that is a direct result of using 'value' instead of Value or value or _value or this.value. And what happens when you have to store another kind of arbitrary number? Will you call it Value2?
Name the class with a more specific and meaningful name and the problem will no longer exist. Don't fix the symptoms - fix the cause.
Even if you only rename it to "DataValue" or 'MySystemValue', you will be doing yourself a great service.
Bowing to popular opinion, I've decided to rename my Value class to DataValue. I'm pretty happy with that name, and it means I don't need any hacks to have the property called Value. So thank you very much to everyone for the feedback.
But, despite the useful answers, I still don't think the question has been answered ideally. None of the proposed solutions do exactly what was asked for, or at least not without side effects like the requirement for an otherwise-superfluous interface or public class. I should probably have been clearer in my question that I was perfectly happy to consider a hack that involved unsafe code, or modification of intermediate language or some such, as my priority was to get the public API of the DLL the way I wanted it, irrespective of whatever messy hacks might lurk hidden within it's source.
So here's the best solution that I could come up with. I haven't actually done it myself (no need now I'm using a different name for the class), but I don't have any reason to suspect that it won't work:
In the solution that contains your C# class-library project, add a new VB class-library project.
In the VB project, create the class (Value in my original example). In VB you'll have no problems adding a property with the same name as the class.
If your VB class has internal methods that need to be referenced by your C# code, reference the C# assembly using InternalsVisibleTo in your VB class.
You should now be able to reference your VB class from your C# project. But when you build the solution you'll get two separate DLLs: one for the C# code and one for the VB code. It looks like the ILMerge tool makes it very straightforward to merge the two DLLs into one (just one call from the command line).
So finally you should have a single DLL that contains the class with the property of the same name, and all the code in your C# project. Other projects that use that DLL (C#, VB, or any other .Net language) should not see your hacky effort - all they'll see is a coherent API with no superfluous public classes or interfaces.

'CompanyName.Foo' is a 'namespace' but is used like a 'type'

Restatement of the question
I'm resurrecting this question because I just ran into this error again today, and I'm still utterly confused why the C# compiler bothers to check for collisions between namespaces and types in contexts where it makes no sense for a namespace to exist.
If I have...
public Foo MyFoo { get; set; }
...why would the compiler care that Foo is both a namespace and a type? Can you declare a property as a namespace instead of a type?
What is the logic behind the "namespace used like type" compiler error? What problem is this saving me from?
[And how do I tag Eric Lippert? :)]
Original Question
The problem
I have a project "Foo" with default namespace CompanyName.Foo. I have a database that's also called "Foo".
And when I run SqlMetal.exe on the database, it generates a class CompanyName.Foo.Models.Foo.
Then, when I attempt to create a property with this class as the type, like this...
using CompanyName.Foo.Models;
...
public Foo DataContext { get; set; }
...I get the error:
'CompanyName.Foo' is a 'namespace' but is used like a 'type'.
I am forced to do...
public CompanyName.Foo.Models.Foo Foo { get; set; } // :-(
Questions:
Why does this error occur? My property declaration doesn't contain CompanyName, so why is this a problem? Simply put: Foo != CompanyName.Foo. Also, just to be sure, I did a search of my entire solution for namespace Foo and came up with zero hits (if I had actually used a namespace Foo, I could understand getting an error).
[answered] Is there any way around fully qualifying Foo every time I want to use it?
[answered] Is there any way to get SqlMetal to name the class anything other than Foo (w/o changing the name of my database)? I can change the namespace using a switch, but I don't know of a way to change the actual class name.
Update
Still seeking an answer to (1).
O.K.W. nailed (2) & (3).
Usings
A request was made for all my using statements:
using System;
using System.ComponentModel;
using System.Data.Linq;
using System.Linq;
using MyCompany.Foo.Models;
how do I tag Eric Lippert?
If you have something you want brought to my attention you can use the "contact" link on my blog.
I'm still utterly confused why the C# compiler bothers to check for collisions between namespaces and types in contexts where it makes no sense for a namespace to exist.
Indeed, the rules here are tricky. Coincidentally, two weeks ago I wrote and posted a series of blog articles about some of these issues closely related to this very issue; they'll actually go live in early March. Watch the blog for details.
UPDATE: The articles mentioned above are here:
Link
Why does this error occur?
Let me rephrase the question into several questions.
What sections of the specification justify the production of this error?
I think that's already been covered satisfactorily in other answers. The type resolution algorithm is extremely well-specified. But just to sum up: being inside something of the right name "binds more tightly" than using something of the right name from the outside. When you say:
using XYZ;
namespace ABC.DEF
{
class GHI : DEF { }
}
that is the same as
using XYZ;
namespace ABC
{
namespace DEF
{
class GHI : DEF { }
}
}
So now we must determine the meaning of DEF. We go from inside to outside. Is there a type parameter of GHI called DEF? No. Look at the container. Is there a member of DEF called DEF? No. Look at the container. Is there a member of ABC called DEF? YES. We're done; we have determined the meaning of DEF, it is a namespace. We discover the meaning of DEF before we ask "does XYZ have a member DEF?"
What design principles influence this design?
One design principle is "names mean the same thing no matter how you use them". The language does not 100% obey this principle; there are situations in which the same name can be used to refer to two different things in the same code. But in general, we strive for a situation where when you see "Foo" two times in the same context, it means the same thing. (See my article on The Color Color Problem for some details on this, as well as my articles on identifying violations of the "simple name" rules.)
One design principle is "no backtracking". We do not ever say in C# "I see that you used a name to refer to something that is not legal to refer to in this context. Let me abandon the result of name binding and start over, looking for something that might work."
A larger principle that underlies the "no backtracking" principle is that C# is not a "guess what the user meant" language. You wrote a program where the best possible binding of an identifier identified a namespace when a type was expected. There are two possibilities. Possibility one: you've made an error that you want to be told about so that you can take action to correct it. Possibility two: you meant for a less-good binding to be the one we choose, and so we should guess from amongst all the possible less-good bindings to figure out which one you probably meant.
That's a good design principle in languages like JScript -- JScript is all about muddling on through when the developer does something crazy. C# is not that kind of language; the feedback we get loud and clear from our developers is tell me when something is broken so I can fix it.
The thing about "no backtracking" is that it makes the language much easier to understand. Suppose you have something like this mess:
namespace XYZ.DEF
{
public class GHI {}
}
namespace QRS.DEF.GHI
{
public class JKL { }
}
...
using QRS;
namespace TUV
{
using XYZ;
namespace ABC
{
namespace DEF
{
class GHI { }
class MNO : DEF.GHI.JKL { }
}
}
}
Work out the base type of MNO. With no backtracking we say "DEF is ABC.DEF". Therefore GHI is ABC.DEF.GHI. Therefore JKL is ABC.DEF.GHI.JKL, which does not exist, error. You must fix the error by giving a type name that lets the compiler identify which DEF you meant.
If we had backtracking, what would we have to do? We get that error, and then we backtrack. Does XYZ contain a DEF? Yes. Does it contain a GHI? Yes. Does it contain a JKL? No. Backtrack again. Does QRS contain an DEF.GHI.JKL? Yes.
That works, but can we logically conclude from the fact that it works that it is the one the user meant?
Who the heck knows in this crazy siutation? We got all kinds of good bindings in there that then went bad very late in the game. The idea that we stumbled upon the desired answer after going down many blind alleys seems highly suspect.
The correct thing to do here is not to backtrack multiple times and try out all kinds of worse bindings for every stage of the lookup. The correct thing to do is to say "buddy, the best possible match for this lookup gives nonsensical results; give me something less ambiguous to work with here please."
An unfortunate fact about writing a language where the compiler by design complains loudly if the best match is something that doesn't work, is that developers frequently say "well, sure, in general I want the compiler to point out all my mistakes -- or, rather, all my coworker's mistakes. But for this specific case, I know what I am doing, so please, compiler, do what I mean, not what I say."
Trouble is, you can't have it both ways. You can't have both a compiler that both enforces rigid rules that make it highly likely that suspicious code will be aggressively identified as erroneous and allow crazy code via compiler heuristics that figure out "what I really meant" when you write something that the compiler quite rightly sees as ambiguous or wrong.
For an object lesson in how lots of pro devs vehemently dislike the effects of a language design that aggressively identifies errors rather than guessing that the developer meant for the worse result to be chosen, see the 116 comments to this article on a minor and rather unimportant aspect of overload resolution:
(Note that I am no longer responding to comments on this issue; I've explained my position over ten times. If all those explanations are not convincing, that's because I'm not a very good convincer.)
And finally, if you really want to test your understanding of how the name resolution rules work in C#, try out this little puzzle. Almost everyone gets it wrong, or gets it right for the wrong reasons. The answer is here.
The clash is between namespace CompanyName.Foo and CompanyName.Foo.Models.Foo, and not Foo. I'm not exactly sure how/why the compiler can't distinguish both though.
You can try using namespace alias to shorten full qualifying Foo
e.g. using coyModels = CompanyName.Foo.Models
From the reference, seems like you can use /context:<type> and /namespace:<name> to specify the data context class (instead of using table name) and namespace.
C# compiler doesn't compile when there is an ambiguity between a class and a namespace with the same name. Unfortunately you just have to namespace the class explicitly or rename the database. In your case the compiler didn't even get to the conflict, it died after resolving Foo as a namespace.
Whenever you have something like this:
using CompanyName.Foo.Models;
namespace CompanyName.Foo {
class Test {
public Foo Model { get; set; } // error CS0118: 'CompanyName.Foo' is a 'namespace' but is used like a 'type'
public Foo1 Model { get; set; } //OK
}
}
namespace CompanyName.Foo.Models {
class Foo1 {
}
class Foo {
}
}
What actually happens is every preceeding level of the namespace is implicitly imported at each level. This makes sense since the nested namespace syntax using dot is the same as nesting namespaces:
namespace CompanyName {
using CompanyName; //<--using1 - Implicit using, since we should be able to access anything within CompanyName implicitly.
namespace Foo {
using CompanyName.Foo; //<-- using2 Same as above
class Test {
public Foo Model { get; set; } //At this stage due to using1 Foo is actually CompanyName.Foo, hence the compiler error
}
}
}
So inside class Test there are two implicit usings:
using CompanyName;
using CompanyName.Foo;
Hence Foo is resolved to the namespace hence the error.
EDIT Good point. I've dug this up from MSDN:
The meaning of a namespace-or-type-name is determined as follows:
If the namespace-or-type-name consists of a single identifier:
If the namespace-or-type-name appears within
the body of a class or struct
declaration, then starting with that
class or struct declaration and
continuing with each enclosing class
or struct declaration (if any), if a
member with the given name exists, is
accessible, and denotes a type, then
the namespace-or-type-name refers to
that member. Note that non-type
members (constants, fields, methods,
properties, indexers, operators,
instance constructors, destructors,
and static constructors) are ignored
when determining the meaning of a
namespace-or-type-name.
Otherwise, starting with the namespace in which the
namespace-or-type-name occurs,
continuing with each enclosing
namespace (if any), and ending with
the global namespace, the following
steps are evaluated until an entity is
located:
If the namespace contains a namespace member with the given
name, then the namespace-or-type-name
refers to that member and, depending
on the member, is classified as a
namespace or a type.
Otherwise, if the namespace has a corresponding
namespace declaration enclosing the
location where the
namespace-or-type-name occurs, then:
If the namespace declaration contains a
using-alias-directive that associates
the given name with an imported
namespace or type, then the
namespace-or-type-name refers to that
namespace or type.
Otherwise, if the namespaces imported by the
using-namespace-directives of the
namespace declaration contain exactly
one type with the given name, then the
namespace-or-type-name refers to that
type.
...
(Bolding is mine) This means that when resolving Foo, matching it against CompanyName.Foo (first bold bit) happens before matching it against the using directive(second bold build).
why can't you just do
using CompanyName.Foo;
...
public Models.Foo DataContext { get; set; }
I had this issue pop up when I was referencing a class in a separate class library, where its type had the same name as the root of the namespace. Initially, when referencing this type in a separate console app project, there was no problem, everything compiled fine. However the reference from a Windows Service project was generating the is a 'namespace' but is used like a 'type'. message. Turns out the Windows Service Project had its Target Framework set to ".NET Framework 4 Client Profile". Changing this to ".NET Framework 4" eliminated the error. Hopefully this helps someone in a similar situation.
I am new to c# and I came into contact with this error upon decompiling a c# application, saving as a project, the attempting to immediately recompile... why the application was able to compile in the first place is beyond me.. however... the problem and solution is quite simple: by default, upon adding a new class, c# uses the same name for a namespace as it does for the class within the namespace!!!!! This is bad because without some hidden identifier explicitly telling which (namespace or type) you are referring to, the compiler can't tell the difference!!!!! doh! way to go c#!!!! ... THE SOLUTION: Instead of renaming a thousand things and double checking all corrections, run the project, when you have the list of errors in front of you, click each in turn to go to each problem. Once at the "foo" in question type a dot (.) after said "foo" such that it displays: foo. .. this should bring up the menu of classes contained within. In this list, double-click "foo" (or just retype the name) changing the original "foo" to "foo.foo" ... Do this for each error and problem solved!!! Voila!!!! I did this to an entire application with complex names, and it worked great! Happy coding! - Tim H.
Because you've used dot notation to separate Company and Foo, you are implicitly creating a Company namespace, with a nested Foo namespace, not Company.Foo as you believe.
That's why this doesn't work:
namespace Company.Foo
{
}
namespace Company.Foo.Models
{
public class TestClass {
public Foo DataContext { get; set; }
}
}
The closest thing to Foo is the nested Foo namespace in the Company namespace. You can however do this:
using Company.Foo;
using Company.Foo.Models;
namespace Company.Foo
{
class Program {
public static void Main() {}
}
}
namespace Company.Foo.Models
{
public class Foo { }
}
public class DataContextClass
{
public Foo DataContext { get; set; } /* Foo here is automatically resolved to Company.Foo.Models.Foo */
}
Edit
Igor said the same thing, but was more technical.
This also happens if you generate unit tests when you have a namespace and a class with the same name. Which you should never do as explained by Eric Lippert here:
http://blogs.msdn.com/b/ericlippert/archive/2010/03/09/do-not-name-a-class-the-same-as-its-namespace-part-one.aspx

Categories