I have a code template which builds files in a project's folder, and uses the properties defined in the partial classes to determine which properties still need to be implemented. As an example:
public partial class Thingy : IThingy
{
public Foo Bar { get; set; }
}
public interface IThingy
{
Foo Bar { get; set; }
Baz Biz { get; set; }
}
and the template is supposed to generate:
public partial class Thingy
{
Baz Biz { get; set; }
}
I can guarantee that the template will generate the remaining info to satisfy the expectations of the interface and thus would even be able to generate the class, except the CSharpCodeProvider balks at the notion of only getting half of the interface implemented in the non-generated partial class. Is there a way to tell the provider to ignore that an interface is being implemented at all?
EDIT: I've given this a little more thought, and figured a workaround in the form of actually reading the source first into a string, removing the interface references, and throwing the string of code to CompileAssemblyFromSource instead of CompileAssemblyFromFile, but that feels super kludgy and will more than likely introduce bugs. Thoughts?
You need to modify the source to remove interface implementation declaration, I think.
Related
I have an inherited settings classes inherited from a base class which I would like to (de)serialise separately (example)
[ProtoContract]
[ProtoInclude(1, typeof(GlobalSettings))]
[ProtoInclude(2, typeof(UserSettings))]
public class BaseSettings
{
}
[ProtoContract]
public class GlobalSettings: BaseSettings
{
[ProtoMember(1)]
public string TempPath { get; set; }
}
[ProtoContract]
public class UserSettings: BaseSettings
{
[ProtoMember(1)]
public int UILanguage { get; set; }
}
Only issue is I cannot afford losing the configuration, can it be done in a way that if UserSettings are no longer inherited from BaseSettings and moved to another assembly to be used independently, (de)serialisation still will be possible (with some sort of conversion or without) without access to GlobalSettings class?
The inheritance is a fundamental part of the serialization model, especially if you ever talk in terms of Deserialize<BaseSettings>. If you only ever do things like Deserialize<GlobalSettings> or Deserialize<UserSettings>, then you might be able to remove the [ProtoInclude]s, but then the issue becomes announcing the members of BaseSettings into the sub-types. There are ways to do that.
I have a class that is generated by a third party tool:
public partial class CloudDataContext : DbContext
{
// ...SNIPPED...
public DbSet<User> Users { get; set; }
}
I create a partial class and then assign an interface so that I can inject this class later:
public partial class CloudDataContext : IDataContext
{
}
The IDataContext has the single property Users.
This won't compile, the compiler complains that the interface isn't implemented.
If I move the interface to the generated class, it works fine. I can't do that though as it's generated code.
How can I apply an interface to a partial class to expose the class as defined above?
The problem must be somewhere else, because you can implement interface in the other part of partial class than it's set on. I just tried following and it compiles just fine:
public interface IFoo
{
int Bar { get; set; }
}
public partial class Foo
{
public int Bar { get; set; }
}
public partial class Foo : IFoo
{
}
The properties probably use different types in interface and class.
Here's a quick checklist. Do the classes have identical:
Names?
Namespaces?
Access modifiers?
Example:
You decide to split an existing class into two files.
The original file's namespace doesn't match its folder path.
Consequently, the new class file you create has a mismatching namespace.
Build fails.
IN my Case problem was that interface Method that was implemented in other part of the partial class was not compiling and C# was giving error of not implemented Method
In my case, the interface method signature didn't mention a value (uint direction) that the actual method expected. This showed up as the interface having errors in one of the partial classes. Make sure that the interface for a method is actually the same as the method signature itself. D'oh.
When I implement an interface for the first time into a class I want either resharper 6 or visual studio 2010 to implement my properties as auto implemented properties and not put in the default value of throw new NonImplementedException();. How can I do this? For example:
public interface IEmployee
{
// want this to stay just like this when implemented into class
ID { get; set; }
}
public class Employee : IEmployee
{
// I do not want the throw new NonImplemented exception
// I want it to just appear as an auto implemented property
// as I defined it in the interface
public int ID
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
Because this happens all the time, I am finding myself having to constantly refactor and manually remove those throw new UnImplimented() exceptions and manually make the properties be auto implemented... a pain! After all, I defined it as an auto implemented property in my interface.
Any help or advice much appreciated! Thanks.
Note: your R# keyboard shortcuts may differ, I am using the Resharper 2.x keyboard schema.
If you declare the interface on the class and then use Alt+Enter and select “Implement members”:
Then you will get the default implementation, which happens to be throwing NotImplementedException, unless you change that.
But if you ignore the suggested course of action and instead use Alt+Insert to open the Generate menu, you can select “Missing members”:
This will open Generate window, where you can select to implement the property (or properties) as auto-implemented:
That will do exactly what you want:
class Employee : IEmployee
{
public int Id { get; set; }
}
After all, I defined it as an auto implemented property in my interface.
No, you didn't. You declared it as a property without an implementation. That's all you can do in an interface: you're just saying that classes implementing the interface must provide the concrete implementations of such properties.
Personally I would be wary of having too many writable properties within interfaces - if this is something you find "happens all the time" I wonder whether you're using interfaces where possibly abstract classes would be more appropriate.
In terms of your exact question: I don't know whether it's possible to change the default implementation either VS or R# provides for interfaces - but I would resist making those changes anyway, to be honest.
EDIT: Under R# options, "Code Generation", you can choose between throwing an exception, returning a default value, or giving uncompilable code. It's possible that this will do what you want. Give it a go, but I'd still strongly urge you to think carefully before going down this path.
An interface is not meant to specify how the methods will be implemented so there is no way around it using the interface. One solution would be to make an abstract base class with the auto-implemented properties and inherit that class instead of directly implementing the interface.
Here's a quick workaround that I found in VS2015. Mark your class as abstract then implement the interface abstractly. This adds the auto properties for you then you just replace the "abstract " with "" in your file. Then you can remove the abstract keyword from your class.
In the case of VS2015 I'm using a find and replace macro as a workaround:
Find:
(\r|\n| |\t)+\{(\r|\n| |\t)+get(\r|\n| |\t)+\{(\r|\n| |\t)+throw(\r|\n| |\t)+new(\r|\n| |\t)+NotImplementedException\(\);(\r|\n| |\t)+\}(\r|\n| |\t)+set(\r|\n| |\t)+\{(\r|\n| |\t)+throw(\r|\n| |\t)+new(\r|\n| |\t)+NotImplementedException\(\);(\r|\n| |\t)+\}(\r|\n| |\t)+\}
replace:
{get;set;}
In addition to Jon's answer... if you really want to change this (out of box) behavior of Visual Studio and creating auto properties when implement interface, you can try one of following...
Use T4 for code generation - http://msdn.microsoft.com/en-us/library/bb126445.aspx
Write a custom plugin for Visual Studio using VS SDK achieve this
It's not related to this question completely, however, a different approach when you have multiple of such properties in an Interface, instead of interface you can have a class and refer to that class as a return type in your main class. You can create a class and refer to that class in your main class. Example
public class Asset
{
public int AssetTrackingID { get; set; }
public Category AssetCategoryInfo { get; set; }
public Manufacturer AssetManufacturerInfo { get; set; }
public ManufacturerModel AssetModelInfo { get; set; }
public Status AssetStatusInfo { get; set; }
public EmployeeDetails AssetEmployeeInfo { get; set; }
public string AssetNumber { get; set; }
public string SerialNumber { get; set; }
public DateTime? AcquiredDate { get; set; }
}
In an MVC project I have the following classes:
public abstract class Browse<T> where T : Browse<T>
public abstract class SqlBrowse<T> : Browse<T> where T : Browse<T>
public class SqlBrowseBoys : SqlBrowse<SqlBrowseBoys>
public class SqlBrowseGirls : SqlBrowse<SqlBrowseGirls>
and the following view model
public class BrowseViewModel
{
public [INTERFACE] People { get; set; }
}
but I need an interface/class in the position labelled [INTERFACE] that can take both SqlBrowseBoys and SqlBrowseGirls so I can use BrowseViewModel in multiple places.
I'd love it if someone could show me how as my brain is now tied in knots. I suspect this will require some change(s) to the classes and that's fine but I currently have no clue what that will be.
Many, many thanks.
Have SqlBrowse<T> implement a non-generic SqlBrowse interface (or abstract class), and then write
public SqlBrowse People { get; set; }
It's hard to tell what changes that will entail to your classes because we don't have their definitions.
I currently have a solution with multiple projects that mostly use the same classes. As a result, it appeared to me that it would be a good idea to add a class library containing these classes in the solution instead of repeating the class in each project.
However, one project I have requires a few additional properties to some of the classes that are specific to that project and will not be used anywhere else. As a result, I thought that I should use partial classes to add these properties. So I have done something like this:
In the class library:
namespace MyClassLibrary
{
public partial class Book
{
public string Title { get; set; }
public string AuthorLast { get; set; }
public string AuthorFirst { get; set; }
public string Publisher { get; set; }
public string Edition { get; set; }
public string ISBN10 { get; set; }
public string ISBN13 { get; set; }
}
}
In the project (MyProject):
namespace MyClassLibrary
{
public partial class Book
{
public string AdditionalProperty { get; set; }
}
}
I have referenced MyClassLibrary in MyProject (a C# windows form app), however when I try to use this class in the codebehind for the form I receive the following error:
class MyClassLibrary.Book
Warning: The type
'MyClassLibrary.Book' in 'C:...
(Project)' conflicts with the imported
type 'MyClassLibrary.Book' in 'C:...
(Class Library DLL)'. Using the type
defined in 'C:...(project)'.
Any idea what I am doing wrong or if my whole approach is bad and I should be doing something else?
Partials are not for spanning assemblies. If you need to add to your class for a more specific type of usage, you should create a derived class:
public class MyFoo
{
public string BasicProperty {get;set;}
}
public class MySpecificFoo : MyFoo
{
public string AnotherProperty {get;set;}
}
In your project requiring the more specific type of MyFoo, utilize MySpecificFoo instead. Since it inherits/derives from MyFoo, it will have all of the properties and functionality of MyFoo, with the additional properties as well. This is part of Polymorphism, which is where real power of OOP lies.
In short, you can't use partial classes across projects. All the source must be compiled at the same time, and that's done per project.
Here's a full discussion on SO about this: Should you use a partial class across projects?
For what you're trying to do, you should instead try to use base classes and inheritance. Or even better object composition.
I think this is more along the lines of what you're trying to achieve.
Put all of your common classes into a class library project and compile it to a DLL.
You can then reference that DLL in external projects. Anytime you need to add a property to it for the external project you can then inherit the class and add the property there.
all wrong. You should consider partial methods instead. Look 'em up. They're exactly what you asked for.