IComparable: Cannot implement an interface member because it is not public [closed] - c#

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm already aware that there are many other similar questions regarding this topic, however looking at the answers and adapting my code in relation to those has proved unsuccessful.
The code below is part of my Artist class, where I use CompareTo to compare between the artist name and the artist name (obj) passed in..
class Artists : IComparable
{
private string artistName;
private string artistMembers;
public int CompareTo(Object obj)
{
Artists otherArtist = (Artists)obj;
return artistName.CompareTo(otherArtist.ArtistName);
}
public Artists(string artist, string members){
ArtistName = artist;
Members = members;
}
public string ArtistName
{
set { artistName = value; }
get { return artistName; }
}
public string Members
{
set { artistMembers = value; }
get { return artistMembers; }
}
}
I really want to avoid making the variables public, which is a solution offered elsewhere, so I was wondering what I need to do to sort this problem out, and what I am doing wrong so I can learn from mistakes.
Thanks in advance.
EDIT 2
Closed VS and recompiled, and suddenly worked. Sorry for time wasting.

I'm assuming from your error that CompareTo is not public in your real code. Implicit interface implementations must be public.
You could implement the interface explicitly, and then clients would have to cast to IComparable to see the method:
int IComparable.CompareTo(Object obj) // will be private unless explicitly using the interface
{
Artists otherArtist = (Artists)obj;
return artistName.CompareTo(otherArtist.ArtistName);
}
Artists a1 = new Artists("Beatles", "Paul, Ringo");
Artists a2 = new Artists("U2", "Bono");
// this will fail:
//int i = a1.CompareTo(a2);
// this will work:
int i = ((IComparable)a1).CompareTo(a2);
However note that your class is internal by default, so the class is not even public.

Related

Cannot convert from '...Generic.List<Game02.Human>' to 'Game02.Human' [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm trying to make functions to "send" NPCs to specific rooms by adding them to the room's humansHere list, and one to get this list (and print it later, but I don't need help with that). But I get this error message:
Argument 1: cannot convert from 'System.Collections.Generic.List<Game02.Human>' to 'Game02.Human'
Once I get that fixed, I'm sure I'll figure out the rest, so feel free to ignore this: I need to know how to call this function for specific rooms. Something like:
LivingRoom.GetHumansHere() or Kitchen.SetHumansHere(_lyndonJohnson). Or will this work as it is?
public class Room
{
public int ID { get; set; }
[...]
private List<Human> humansHere;
public List<Human> GetHumansHere()
{
return humansHere;
}
public void SetHumansHere(List<Human> x)
{
humansHere.Add(x);
}
}
public class Human : LivingCreature
{
public int Gold { get; set; }
public List<InventoryItem> Inventory { get; set; }
public Human(string name, int currentHitPoints, int maximumHitPoints, int gold) : base(name, currentHitPoints, maximumHitPoints)
{
Gold = gold;
}
}
Thank you to Dmitry for making it work, and thank you to Jonathan for explaining the problem:
The problem is you are trying to add a LIST of humans to a list rather than a single human to a list
Two possibilities:
If you want to add one person only, change method's signature:
public void SetHumansHere(Human person)
{
if (null == person)
throw new ArgumentNullException(nameof(person));
humansHere.Add(person);
}
If you want to add a collection of persons in one go, use AddRange
// IEnumerable<Human> - let's generalize the method
// and allow to add not only List, but other collections, say, array
public void SetHumansHere(IEnumerable<Human> persons)
{
if (null == persons)
throw new ArgumentNullException(nameof(persons));
humansHere.AddRange(persons);
}
you need to use List.AddRange, Adds the elements of the specified collection to the end of the List.
public void SetHumansHere(List<Human> x)
{
humansHere.AddRange(x);
}

Is there a good practice of setting default values in an constructor? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Consider a simple class
public class MyClass
{
private int myProperty
...
public int MyProperty
{
get
{
return myProperty;
}
set
{
// some evaluation/condition
myProperty= value;
}
}
...
}
Now, if I want to create an empty constructor where I set default values for the class properties I could do this either this way:
public MyClass()
{
myProperty = 1;
...
}
or this way:
public MyClass()
{
MyProperty = 1;
...
}
Both examples seem valid, since I would never set a default value, that doesn't meet the requirements in the setter evaluation.
The question is, is there a best practice or doesn't it matter anyway?
What would be the advantage of one or the other be (as I can't find any)? Is there some reference, where this question is adressed?
So far I have come across code from many different developers that use either or both ways...
You can use both. But i prefer the first one. Why? Because the value that the property uses is directly assigned. For C# 6 above, you can use default value in a property directly without using constructor.
public class Person
{
public string FirstName { get; set; } = "<first_name>";
public string LastName { get; set; } = "<last_name">;
}
I personally like to set it as you done in first block.
For me it serve as additional fact of method is constructing object, not using alredy constructed. Also it makes me sure that properties is not called (they transform to set/get functions which results in couple of excess instruction).
But i believe that both variants are valid and maybe compiler optimizes properties to direct assignment.
For simple data first method is ok. But on more complex data, you could have a condition in the set (depending to another variable for example, set { if (Config.TestEnv) ...} so if you directly set the private value, you could be in trouble.

Dictionary containing List [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
The below code:
public struct Value
{
List<string> RFcode;
int found;
int expected;
public int Found { get { return found; } }
public int Expected { get { return expected; } }
public List<string> Code { get { return RFcode; } }
public Value(int f, int exp, string s)
{
this.found = f;
this.expected = exp;
RFcode.Add(s);
}
}
is Invalid. On VS debug I get :
Error 1 Field 'BE_EOR.InvCyclic.Value.RFcode' must be fully assigned before control is returned to the caller
Error 2 Use of possibly unassigned field 'RFcode'
Please try this one:
List<string> RFcode = new List<string>();
The reason, why you get this error is the fact, that you haven't created a list, which will hold the strings you want. However, you try to add elements in this list:
RFcode.Add(s);
This line of code, List<string> RFcode;, it justs defines a variable called RFcode, that will keep a reference to a List of strings. Neither it creates a list nor it assings it to this variable.
Update
As already Christian Sauer has pointed out and Kensei have reminded it to us, it would be better you use a class rather than the struct you use:
public class Value
{
public List<string> RFCode { get; set; }
public int Found { get; set; }
public int Expected { get; set; }
public Value(string s, int found, int expected)
{
RFCode = new List<string> { s };
Found = found;
Expected = expected;
}
}
However, at this point I have to raise a question. Why are you using a List of strings, since you only pass a string to your constructor? If that's the case, to pass only a string, I don't think that's a good design, since you don't use the most appropriate type for that you want.

Why i can not input set in my code? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
When writing out a property in visual studio, the IDE autocompletes the wrong text and interrupts my flow.
class Person
{
private int age;
public int Age;
{
AppDomainSetup //
}
AppDomainSetup is given when I've typed set. Why is the IDE confused?
You should remove ; after "Age".
It is:
internal class Person
{
private int age;
public int Age { set; get; }
}
Try
internal class Person
{
private int age;
public int Age { set; get; }
}
The more complete answer is that you've ended the field Age and the IDE is reading what you've written and is expecting a Type (among a few other contextually based options, of which set is NOT one). You've only written set, and the best match for set for a type in the given context is AppDomainSetup because it is the first Type in whose name the substring set is found. The autocomplete behavior is to input the selected suggestion when you press space.
To correct this (or to stop confusing intellisense), don't put a colon after the property name.
public int Age { set // and continue typing

C# type design Question [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
This might sound a little stupid but I am still curious about what the community thinks.
So I have a WebService returning a UpdateInfo class.
Now consider the following definitions
public enum TTCFileType
{
API = 0,
BOOKMARK,
TICKMARK
}
public class FileUpdateInfo
{
public string FileName;
public string FileDownLoadURI;
public TTCFileType FileType;
}
public class UpdateInfo
{
public FileUpdateInfo fuInfo;
//Other
}
Here is the issue, if the TTCFileType has the value TICKMARK then I need another enum viz Tickmark Type( the biz logic demands this information). I am wondering what is the best way to represent that. I dont want a method signature where I have something Like
UpdateMethod( UpdateInfo ui, TickMarkType tt)
where I examine tt if ui.fuInfo.FileType == TTCFileType.TICKMARK
I guess I am trying to find an semi elegant way at least to represent the conditional requirement for getting the second piece of information out ( in many ways this so reminds of VARIANTS , if var.VT == VT_[thingy] then use vt.[thingy] and yes I know how c# developers feel about unions :-)
Anyway curious if there is a nifty way to do this
Thanks
Just include TickMarkType field to FileUpdateInfo class?
I'd be tempted to go with something like:
public enum TTCFileType
{
API = 0,
BOOKMARK,
TICKMARK_TYPE1 = 100,
TICKMARK_TYPE2 = 101,
TICKMARK_TYPE3 = 102
}
and so on. Depending on how many there are and how manageable it would feel within the wider context of your code.
Ideally, you need two additional structure(s)
public enum TickmarkType
{
TYPE1=0,
TYPE2
}
public class TickMarkFileUpdateInfo : FileUpdateInfo
{
public TickmarkType type;
}
And then read about polymorphism in web services
Store the enum value as an int. Add some offset to the value for your second enum (e.g., 1000) so that if the value is from the first enum it's 0..2 and if it's from the second enum it's 1000.1010 or whatever. Then you can set 2 properties, one that returns a nullable TTCFileType and the other that returns a nullable TickType, to read and write the values into the int field.
It seems like you're trying to use only data structures, when using OO features (such as inheritance) might help you. Maybe this example code gives you some ideas:
public class Update
{
// ... ?
}
public class FileUpdate : Update
{
public virtual string Name { get; set; }
public virtual string DownloadUri { get; set; }
public virtual bool IsTickMarked { get; set; }
}
public class ApiFileUpdate : FileUpdate
{
// ...
}
public class BookmarkFileUpdate : FileUpdate
{
// ...
}
You can still serialize these, given the proper serialization attributes.
In fact, you can define (potentially virtual) methods on these various classes, and actually use them to implement your program.
Overly segregating your data and code is known as the Anemic Domain Model Anti-Pattern.

Categories

Resources